#if (FEATURE_MODE == 0)
/**
 @file sys_usw_ipfix.c

 @author  Copyright (C) 2013 Centec Networks Inc.  All rights reserved.

 @date 2013-10-17

 @version v3.0
*/

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/

#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_const.h"
#include "ctc_ipfix.h"
#include "ctc_interrupt.h"
#include "ctc_warmboot.h"
#include "ctc_spool.h"

#include "sys_usw_common.h"
#include "sys_usw_chip.h"
#include "sys_usw_dma.h"
#include "sys_usw_ipfix.h"
#include "sys_usw_ftm.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_register.h"
#include "sys_usw_interrupt.h"
#include "usw/include/drv_common.h"
#include "sys_usw_scl_api.h"
#include "sys_usw_acl_api.h"

#include "drv_api.h"

/****************************************************************
*
* Defines and Macros
*
****************************************************************/
sys_ipfix_master_t  *p_usw_ipfix_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};
/*for protect mutli-chip callback function*/
sal_mutex_t*   p_ipfix_cb_mutex = NULL;

#define SYS_IPFIX_INIT_CHECK(lchip) \
    do { \
        LCHIP_CHECK(lchip);\
        if (NULL == p_usw_ipfix_master[lchip]){ \
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " Feature not initialized \n");\
        return CTC_E_NOT_INIT;\
 } \
    } while (0)

#define IPFIX_TRAVERSE_TYPE_PROCESS(dump_info, key_type, is_remove,dir)\
    do{\
            ipfix_data.key_index = DRV_IS_DUET2(lchip)?ipfix_data.key_index:ipfix_data.key_index/2;\
            ipfix_data.key_index = SYS_IPFIX_GET_ADINDEX(ipfix_data.key_index, dir);\
                if(is_remove)\
                {\
                    if(CTC_E_NONE == ((ctc_ipfix_traverse_remove_cmp)fn)(&ipfix_data, p_data->user_data))\
                    {\
                        _sys_usw_ipfix_delete_entry_by_index(lchip, key_type, ipfix_data.key_index,dir, 1);\
                        _sys_usw_ipfix_delete_entry_by_index(lchip, key_type, ipfix_data.key_index,dir, 0);\
                    }\
                }\
                else if(traverse_action == SYS_IPFIX_DUMP_ENYRY_INFO)\
                    {\
                        ((ctc_ipfix_traverse_fn)fn)(&ipfix_data, &dump_info);\
                    }\
                    else\
                    {\
                        ((ctc_ipfix_traverse_fn)fn)(&ipfix_data, p_data->user_data);\
                    }\
    }while(0)

#define SYS_IPFIX_DEF_K(DIR, TYPE) \
            p_kset = p_usw_ipfix_master[lchip]->kset_db[DIR][TYPE];\
            CTC_BMP_SET(key_type_bmp[DIR], (TYPE));
#define SYS_IPFIX_DEF_F(FIELD)            CTC_BMP_SET(((p_kset)->w), (FIELD));

STATIC int32
_sys_usw_ipfix_get_entry_by_key(uint8 lchip, sys_ipfix_param_t* param, uint32* rst_hit, uint32* rst_key_index);
extern void
_sys_usw_ipfix_process_isr(ctc_ipfix_data_t* info, void* userdata);
extern int32
sys_usw_ipfix_ftm_cb(uint8 lchip, sys_ftm_specs_info_t* specs_info);
STATIC int32
sys_usw_ipfix_wb_sync(uint8 lchip,uint32 app_id);
STATIC int32
sys_usw_ipfix_wb_restore(uint8 lchip);
STATIC int32
_sys_usw_ipfix_dump_sample_spool_db(void *node, void* user_date);
extern int32
sys_usw_ipfix_dump_db(uint8 lchip, sal_file_t p_f, ctc_global_dump_db_t* p_dump_param);
extern int32
sys_tmm_get_hw_drop_class_id(uint8 lchip, uint32 ctc_drop_reason, ctc_direction_t dir, uint32 * p_classid);
extern int32
sys_usw_ipfix_npm_im_flow_en(uint8 lchip, uint8 enable);
extern int32
sys_usw_ipfix_cb_init(uint8 lchip);
extern uint8 ctc_at_hash_type[];
extern uint8 sys_at_hash_type[];
/* Do Not change the following data anyway*/
#define SYS_USW_PROFILE0_SEED 4094
#define SYS_USW_PROFILE2_SEED 4095
#define SYS_USW_PROFILE3_SEED 4094

#define SYS_USW_PROFILE0_NUM_CNT 465
#define SYS_USW_PROFILE2_NUM_CNT 511
#define SYS_USW_PROFILE3_NUM_CNT 465

#define SYS_IPFIX_FLEX_KEY_VEC_SIZE               256
#define SYS_IPFIX_FLEX_KEY_VEC_BLOCK_SIZE         16
#define SYS_IPFIX_FLOW_CONFIG_SIZE               256


uint8 ctc_hash_type[]={
CTC_IPFIX_KEY_NUM,
CTC_IPFIX_KEY_HASH_MAC,
CTC_IPFIX_KEY_HASH_L2_L3,
CTC_IPFIX_KEY_HASH_IPV4,
CTC_IPFIX_KEY_HASH_IPV6,
CTC_IPFIX_KEY_HASH_MPLS,
CTC_IPFIX_KEY_HASH_IPV4,
CTC_IPFIX_KEY_HASH_IPV6
};

uint8 sys_hash_type[]={
SYS_IPFIX_HASH_TYPE_L2,
SYS_IPFIX_HASH_TYPE_L2L3,
SYS_IPFIX_HASH_TYPE_IPV4,
SYS_IPFIX_HASH_TYPE_IPV6,
SYS_IPFIX_HASH_TYPE_MPLS,
SYS_IPFIX_HASH_TYPE_IPV6_SHORT
};


static uint16 sys_usw_ipfix_random_data[4][512] = {
    {
        12 ,19 ,24 ,27 ,38 ,49 ,54 ,70 ,73 ,77 ,78 ,99 ,103 ,108 ,141 ,146 ,153 ,154 ,157 ,183 ,184 ,199 ,204 ,207 ,216 ,226 ,
        229 ,242 ,273 ,282 ,286 ,292 ,304 ,307 ,308 ,315 ,331 ,332 ,347 ,357 ,366 ,369 ,399 ,408 ,415 ,421 ,433 ,434 ,442 ,
        453 ,458 ,462 ,480 ,484 ,487 ,495 ,496 ,521 ,537 ,542 ,547 ,564 ,567 ,572 ,579 ,584 ,588 ,609 ,610 ,614 ,617 ,630 ,
        663 ,664 ,668 ,674 ,690 ,693 ,694 ,701 ,714 ,733 ,736 ,739 ,744 ,759 ,779 ,788 ,795 ,796 ,799 ,817 ,821 ,830 ,841 ,
        842 ,862 ,867 ,868 ,884 ,906 ,917 ,925 ,926 ,928 ,944 ,951 ,960 ,968 ,971 ,975 ,991 ,993 ,997 ,1002 ,1030 ,1041 ,
        1042 ,1049 ,1075 ,1080 ,1084 ,1092 ,1095 ,1100 ,1107 ,1129 ,1134 ,1145 ,1159 ,1168 ,1171 ,1176 ,1197 ,1210 ,1213 ,
        1218 ,1221 ,1222 ,1229 ,1234 ,1255 ,1256 ,1260 ,1284 ,1299 ,1300 ,1326 ,1329 ,1337 ,1338 ,1345 ,1349 ,1358 ,1380 ,
        1387 ,1388 ,1391 ,1403 ,1425 ,1429 ,1455 ,1456 ,1464 ,1467 ,1471 ,1472 ,1479 ,1488 ,1509 ,1517 ,1518 ,1530 ,1555 ,
        1559 ,1564 ,1577 ,1590 ,1593 ,1597 ,1598 ,1601 ,1606 ,1622 ,1635 ,1643 ,1660 ,1682 ,1685 ,1704 ,1719 ,1724 ,1727 ,
        1731 ,1735 ,1736 ,1762 ,1769 ,1770 ,1773 ,1789 ,1793 ,1813 ,1814 ,1822 ,1835 ,1851 ,1852 ,1856 ,1859 ,1860 ,1867 ,
        1876 ,1889 ,1898 ,1902 ,1920 ,1936 ,1940 ,1943 ,1951 ,1973 ,1978 ,1982 ,1985 ,1986 ,1994 ,2005 ,2024 ,2031 ,2047 ,
        2054 ,2057 ,2061 ,2083 ,2084 ,2087 ,2099 ,2124 ,2139 ,2140 ,2150 ,2161 ,2162 ,2169 ,2184 ,2191 ,2200 ,2213 ,2214 ,
        2221 ,2226 ,2258 ,2265 ,2269 ,2279 ,2288 ,2291 ,2295 ,2296 ,2308 ,2316 ,2319 ,2331 ,2337 ,2342 ,2353 ,2382 ,2385 ,
        2393 ,2394 ,2398 ,2416 ,2420 ,2427 ,2437 ,2442 ,2445 ,2446 ,2458 ,2468 ,2479 ,2511 ,2512 ,2520 ,2523 ,2533 ,2546 ,
        2549 ,2563 ,2568 ,2572 ,2588 ,2594 ,2598 ,2601 ,2633 ,2646 ,2653 ,2654 ,2659 ,2675 ,2676 ,2690 ,2697 ,2698 ,2717 ,
        2720 ,2727 ,2743 ,2760 ,2775 ,2776 ,2780 ,2783 ,2802 ,2806 ,2813 ,2825 ,2830 ,2846 ,2848 ,2851 ,2859 ,2900 ,2907 ,
        2911 ,2913 ,2929 ,2933 ,2934 ,2942 ,2944 ,2955 ,2959 ,2977 ,2978 ,2981 ,2986 ,2997 ,3018 ,3034 ,3037 ,3040 ,3060 ,
        3063 ,3071 ,3075 ,3076 ,3091 ,3110 ,3117 ,3118 ,3129 ,3154 ,3158 ,3161 ,3180 ,3187 ,3192 ,3195 ,3196 ,3202 ,3206 ,
        3213 ,3239 ,3240 ,3244 ,3247 ,3256 ,3271 ,3287 ,3309 ,3314 ,3321 ,3322 ,3329 ,3334 ,3342 ,3345 ,3364 ,3371 ,3375 ,
        3396 ,3408 ,3411 ,3419 ,3438 ,3449 ,3454 ,3460 ,3463 ,3471 ,3472 ,3498 ,3501 ,3514 ,3525 ,3537 ,3538 ,3541 ,3546 ,
        3568 ,3579 ,3583 ,3585 ,3586 ,3593 ,3606 ,3627 ,3628 ,3644 ,3651 ,3667 ,3668 ,3671 ,3676 ,3702 ,3705 ,3709 ,3712 ,
        3715 ,3719 ,3720 ,3735 ,3746 ,3753 ,3757 ,3778 ,3797 ,3798 ,3805 ,3816 ,3832 ,3839 ,3840 ,3844 ,3851 ,3873 ,3881 ,
        3882 ,3886 ,3902 ,3905 ,3921 ,3926 ,3947 ,3956 ,3964 ,3967 ,3970 ,3973 ,3989 ,4000 ,4008 ,4011 ,4031 ,4048 ,4052 ,
        4063 ,4074 ,4085 ,4090 ,4093 ,4094
    },
    {
        /*zero, just for code simple*/
    },
    {
        1, 2, 3, 4, 6, 7, 9, 11, 13, 14, 19, 23, 26, 28, 29, 37, 39, 46, 52, 57, 58, 74, 78, 93, 105, 111, 115, 116, 148, 157,
        177, 186, 197, 211, 222, 223, 231, 233, 235, 296, 314, 315, 317, 333, 334, 352, 354, 355, 359, 372, 373, 395, 422,
        444, 447, 463, 464, 466, 467, 470, 477, 484, 503, 513, 534, 536, 556, 592, 614, 616, 625, 628, 629, 631, 634, 646,
        655, 666, 668, 669, 704, 708, 709, 711, 718, 722, 745, 746, 790, 797, 819, 823, 832, 839, 844, 846, 884, 888, 889,
        895, 896, 905, 915, 925, 926, 927, 928, 929, 931, 932, 933, 934, 937, 940, 942, 944, 948, 955, 957, 968, 974, 979,
        980, 983, 1001, 1005, 1007, 1024, 1026, 1033, 1068, 1073, 1079, 1082, 1107, 1112, 1140, 1145, 1149, 1152, 1177, 1178,
        1181, 1185, 1187, 1191, 1204, 1223, 1228, 1232, 1233, 1235, 1245, 1248, 1250, 1252, 1255, 1256, 1258, 1259, 1261,
        1263, 1267, 1268, 1269, 1274, 1293, 1310, 1318, 1320, 1332, 1337, 1338, 1339, 1365, 1366, 1368, 1378, 1408, 1417,
        1418, 1419, 1422, 1436, 1437, 1444, 1473, 1480, 1490, 1491, 1492, 1536, 1539, 1575, 1577, 1580, 1582, 1594, 1595,
        1638, 1647, 1651, 1652, 1665, 1679, 1683, 1688, 1692, 1694, 1706, 1721, 1768, 1777, 1778, 1791, 1792, 1798, 1811,
        1825, 1831, 1850, 1853, 1854, 1856, 1859, 1861, 1863, 1864, 1865, 1866, 1869, 1871, 1874, 1875, 1881, 1885, 1888,
        1897, 1899, 1910, 1911, 1914, 1931, 1936, 1937, 1942, 1949, 1957, 1959, 1961, 1966, 2003, 2010, 2014, 2047, 2048,
        2049, 2051, 2053, 2062, 2066, 2103, 2136, 2146, 2159, 2165, 2205, 2206, 2214, 2215, 2224, 2225, 2227, 2234, 2280,
        2281, 2286, 2290, 2299, 2304, 2315, 2316, 2326, 2355, 2356, 2360, 2362, 2371, 2375, 2382, 2402, 2409, 2446, 2457,
        2459, 2464, 2467, 2471, 2490, 2492, 2496, 2500, 2505, 2510, 2511, 2512, 2513, 2514, 2516, 2519, 2520, 2522, 2526,
        2535, 2537, 2538, 2539, 2548, 2550, 2560, 2564, 2587, 2589, 2601, 2618, 2620, 2622, 2624, 2636, 2637, 2638, 2641,
        2643, 2650, 2659, 2664, 2665, 2670, 2672, 2674, 2675, 2677, 2678, 2681, 2682, 2685, 2707, 2708, 2717, 2730, 2731,
        2732, 2737, 2757, 2766, 2784, 2788, 2793, 2816, 2817, 2835, 2836, 2839, 2845, 2873, 2874, 2889, 2895, 2901, 2908,
        2947, 2960, 2978, 2980, 2983, 2985, 2997, 3003, 3013, 3016, 3019, 3026, 3071, 3072, 3073, 3079, 3099, 3150, 3151,
        3155, 3160, 3161, 3165, 3188, 3191, 3205, 3206, 3211, 3228, 3249, 3277, 3294, 3303, 3304, 3305, 3308, 3317, 3323,
        3328, 3330, 3342, 3348, 3357, 3359, 3360, 3366, 3367, 3369, 3373, 3377, 3380, 3383, 3384, 3385, 3388, 3389, 3390,
        3401, 3402, 3406, 3413, 3431, 3440, 3442, 3444, 3456, 3495, 3498, 3502, 3537, 3546, 3549, 3554, 3556, 3557, 3561,
        3583, 3584, 3597, 3623, 3628, 3650, 3651, 3653, 3662, 3672, 3700, 3702, 3706, 3709, 3712, 3719, 3722, 3726, 3728,
        3731, 3732, 3734, 3738, 3739, 3740, 3742, 3743, 3748, 3749, 3751, 3763, 3768, 3770, 3776, 3795, 3797, 3799, 3821,
        3822, 3826, 3828, 3862, 3873, 3874, 3884, 3899, 3915, 3917, 3918, 3919, 3922, 3932, 3946, 3961, 4006, 4007, 4021,
        4028, 4051, 4073, 4084, 4090, 4093, 4094, 4095
    },
    {
        14, 29, 35, 37, 59, 67, 69, 70, 75, 85, 94, 99, 117, 118, 130, 135, 138, 140, 143, 151, 170, 188, 191, 199, 212, 234,
        236, 242, 260, 271, 273, 276, 281, 284, 287, 300, 303, 327, 340, 353, 377, 383, 398, 413, 424, 432, 438, 454, 461, 464,
        469, 470, 472, 477, 485, 486, 496, 520, 523, 542, 547, 552, 563, 566, 568, 571, 574, 582, 600, 606, 608, 655, 657, 663,
        681, 698, 705, 706, 727, 737, 746, 753, 754, 759, 762, 767, 770, 796, 809, 826, 836, 849, 850, 865, 866, 868, 873, 876,
        882, 889, 909, 923, 928, 933, 936, 939, 941, 944, 955, 971, 973, 981, 992, 1011, 1033, 1041, 1047, 1071, 1084, 1092,
        1095, 1105, 1127, 1132, 1137, 1140, 1143, 1145, 1148, 1165, 1166, 1176, 1189, 1198, 1200, 1205, 1208, 1213, 1214, 1216,
        1240, 1246, 1269, 1291, 1309, 1310, 1315, 1318, 1323, 1325, 1326, 1334, 1341, 1355, 1357, 1363, 1382, 1397, 1410, 1412,
        1434, 1455, 1468, 1474, 1492, 1495, 1506, 1508, 1511, 1514, 1519, 1524, 1535, 1537, 1540, 1546, 1548, 1553, 1562, 1580,
        1593, 1594, 1601, 1618, 1642, 1644, 1652, 1672, 1691, 1699, 1701, 1725, 1728, 1731, 1733, 1736, 1741, 1747, 1752, 1765,
        1776, 1779, 1800, 1819, 1838, 1846, 1856, 1867, 1872, 1875, 1878, 1883, 1886, 1888, 1891, 1910, 1922, 1929, 1938, 1943,
        1945, 1946, 1951, 1961, 1962, 1983, 1985, 2002, 2023, 2041, 2047, 2055, 2065, 2066, 2081, 2082, 2090, 2095, 2097, 2106,
        2113, 2119, 2143, 2154, 2169, 2184, 2190, 2198, 2211, 2224, 2254, 2264, 2267, 2275, 2278, 2280, 2283, 2286, 2291, 2296,
        2309, 2331, 2333, 2339, 2352, 2376, 2379, 2397, 2400, 2411, 2416, 2421, 2424, 2427, 2429, 2433, 2452, 2466, 2473, 2481,
        2482, 2484, 2489, 2492, 2514, 2516, 2538, 2553, 2564, 2583, 2594, 2618, 2620, 2631, 2636, 2642, 2647, 2650, 2652, 2655,
        2668, 2671, 2682, 2693, 2702, 2707, 2709, 2710, 2715, 2718, 2725, 2726, 2739, 2765, 2782, 2795, 2803, 2805, 2816, 2821,
        2822, 2824, 2829, 2838, 2845, 2848, 2869, 2870, 2893, 2910, 2912, 2918, 2936, 2948, 2967, 2985, 2991, 2993, 3009, 3012,
        3017, 3020, 3023, 3028, 3039, 3049, 3068, 3071, 3075, 3080, 3088, 3093, 3096, 3101, 3104, 3107, 3125, 3147, 3160, 3181,
        3187, 3189, 3202, 3217, 3236, 3258, 3260, 3274, 3281, 3284, 3289, 3290, 3292, 3305, 3306, 3324, 3330, 3345, 3369, 3375,
        3383, 3394, 3399, 3401, 3402, 3407, 3410, 3417, 3439, 3449, 3450, 3456, 3459, 3462, 3467, 3470, 3472, 3483, 3494, 3504,
        3507, 3531, 3544, 3552, 3558, 3582, 3592, 3598, 3600, 3621, 3638, 3656, 3677, 3678, 3685, 3688, 3693, 3694, 3701, 3710,
        3713, 3732, 3735, 3745, 3748, 3751, 3753, 3756, 3767, 3772, 3777, 3783, 3801, 3820, 3839, 3844, 3847, 3858, 3876, 3887,
        3890, 3892, 3895, 3898, 3903, 3914, 3922, 3924, 3948, 3967, 3971, 3995, 3997, 4005, 4022, 4045, 4046, 4059, 4070, 4077,
        4083, 4086, 4091, 4093, 4094
    }
};

/****************************************************************************
 *
* Function
*
*****************************************************************************/
uint32
_sys_usw_ipfix_get_tbl_id_by_type(uint8 lchip, uint8 key_type, uint8 dir)
{
    uint32 tbl_id = 0;
    sys_ipfix_flexed_key_t* p_flexed_key = NULL;
    uint32 tbl_id_array[]=
    {
    DsIpfixL2HashKey_t,
    DsIpfixL2L3HashKey_t,
    DsIpfixL3Ipv4HashKey_t,
    DsIpfixL3Ipv6HashKey_t,
    DsIpfixL3MplsHashKey_t,
    DsIpfixUdfHashKey_t,
    DsIpfixUdfShortHashKey_t,
    DsIpfixL3Ipv4ShortHashKey_t,
    DsIpfixL3Ipv6ShortHashKey_t,
    DsIpfixL3Ipv4ShortHashKey_t
    };

    if (key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
    {
        tbl_id = tbl_id_array[key_type];
    }
    else
    {
        p_flexed_key = ctc_vector_get(p_usw_ipfix_master[lchip]->flex_key_vec, (key_type | (dir << 7)));
        if (!p_flexed_key)
        {
            return CTC_E_NOT_EXIST;
        }
        switch (p_flexed_key->origin_key_type)
        {
            case CTC_IPFIX_KEY_HASH_IPV4_SINGLE:
            case CTC_IPFIX_KEY_HASH_UDF_SINGLE:
                tbl_id = (p_flexed_key->mode == CTC_FIELD_FLEX_KEY_MODE_DOUBLE_APPEND)? DsIpfixXKeyDoubleHashKey_t :DsIpfixXKeySingleHashKey_t;
                break;
            case CTC_IPFIX_KEY_HASH_MAC:
            case CTC_IPFIX_KEY_HASH_IPV4:
            case CTC_IPFIX_KEY_HASH_MPLS:
            case CTC_IPFIX_KEY_HASH_IPV6_SINGLE:
            case CTC_IPFIX_KEY_HASH_UDF:
                tbl_id = (p_flexed_key->mode == CTC_FIELD_FLEX_KEY_MODE_DOUBLE_APPEND)? DsIpfixXKeyQuadHashKey_t :DsIpfixXKeyDoubleHashKey_t ;
                break;
            case CTC_IPFIX_KEY_HASH_IPV6:
            case CTC_IPFIX_KEY_HASH_L2_L3:
                tbl_id = DsIpfixXKeyQuadHashKey_t;
                break;
            default:
                break;
        }
    }
    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && p_usw_ipfix_master[lchip]->short_mode)
    {
        switch (key_type)
        {
            case CTC_IPFIX_KEY_HASH_IPV4:
            case CTC_IPFIX_KEY_HASH_MPLS:
                tbl_id = DsIpfixL3Ipv4ShortHashKey_t;
                break;
            case CTC_IPFIX_KEY_HASH_IPV6:
                tbl_id = DsIpfixL3Ipv6ShortHashKey_t;
                break;
            case CTC_IPFIX_KEY_HASH_UDF:
                tbl_id = DsIpfixUdfShortHashKey_t;
                break;
            default:
                break;
        }
    }
    return tbl_id;
}

uint32
_sys_usw_ipfix_get_tbl_id_by_dir(uint8 lchip, uint32 tbl_id, uint8 dir)
{
    uint32 out_tbl_id = 0;

    if (DRV_IS_DUET2(lchip))
    {
        return tbl_id;
    }
    else if(!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        switch(tbl_id)
        {
        case DsIpfixL2HashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)?DsIpfixL2HashKey0_t:DsIpfixL2HashKey1_t;
            break;
        case DsIpfixL2L3HashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)?DsIpfixL2L3HashKey0_t:DsIpfixL2L3HashKey1_t;
            break;
        case DsIpfixL3Ipv4HashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)?DsIpfixL3Ipv4HashKey0_t:DsIpfixL3Ipv4HashKey1_t;
            break;
        case DsIpfixL3Ipv6HashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)?DsIpfixL3Ipv6HashKey0_t:DsIpfixL3Ipv6HashKey1_t;
            break;
        case DsIpfixL3MplsHashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)?DsIpfixL3MplsHashKey0_t:DsIpfixL3MplsHashKey1_t;
            break;
        case DsIpfixUdfHashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)? DsIpfixUdfHashKey0_t : DsIpfixUdfHashKey1_t;
            break;
        case DsIpfixUdfShortHashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)? DsIpfixUdfShortHashKey0_t : DsIpfixUdfShortHashKey1_t;
            break;
        case DsIpfixL3Ipv4ShortHashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)? DsIpfixL3Ipv4ShortHashKey0_t : DsIpfixL3Ipv4ShortHashKey1_t;
            break;
        case DsIpfixL3Ipv6ShortHashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)? DsIpfixL3Ipv6ShortHashKey0_t : DsIpfixL3Ipv6ShortHashKey1_t;
            break;
        case DsIpfixXKeySingleHashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)? DsIpfixXKeySingleHashKey0_t : DsIpfixXKeySingleHashKey1_t;
            break;
        case DsIpfixXKeyDoubleHashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)? DsIpfixXKeyDoubleHashKey0_t : DsIpfixXKeyDoubleHashKey1_t;
            break;
        case DsIpfixXKeyQuadHashKey_t:
            out_tbl_id = (dir == CTC_INGRESS)? DsIpfixXKeyQuadHashKey0_t : DsIpfixXKeyQuadHashKey1_t;
            break;
        #if 0
        case IpfixL2HashFieldSelect_t:
            out_tbl_id = (dir == CTC_INGRESS)?IpfixL2HashFieldSelect0_t:IpfixL2HashFieldSelect1_t;
            break;
        case IpfixL2L3HashFieldSelect_t:
            out_tbl_id = (dir == CTC_INGRESS)?IpfixL2L3HashFieldSelect0_t:IpfixL2L3HashFieldSelect1_t;
            break;
        case IpfixL3Ipv4HashFieldSelect_t:
            out_tbl_id = (dir == CTC_INGRESS)?IpfixL3Ipv4HashFieldSelect0_t:IpfixL3Ipv4HashFieldSelect1_t;
            break;
        case IpfixL3Ipv6HashFieldSelect_t:
            out_tbl_id = (dir == CTC_INGRESS)?IpfixL3Ipv6HashFieldSelect0_t:IpfixL3Ipv6HashFieldSelect1_t;
            break;
        case IpfixL3MplsHashFieldSelect_t:
            out_tbl_id = (dir == CTC_INGRESS)?IpfixL3MplsHashFieldSelect0_t:IpfixL3MplsHashFieldSelect1_t;
            break;
#endif
        case DsIpfixSessionRecord_t:
            out_tbl_id = (dir == CTC_INGRESS)?DsIpfixSessionRecord0_t:DsIpfixSessionRecord1_t;
            break;
        default:
            out_tbl_id = tbl_id;
            break;
        }
    }
    else
    {
        if(tbl_id == DsIpfixSessionRecord_t)
        {
            tbl_id = (p_usw_ipfix_master[lchip]->short_mode ? DsIpfixSessionHalfRecord0_t : DsIpfixSessionFullRecord0_t);
        }
        switch(tbl_id)
        {
        case DsIpfixSessionFullRecord0_t:
        case DsIpfixSessionFullRecord1_t:
            out_tbl_id = (dir == CTC_INGRESS)?DsIpfixSessionFullRecord0_t:DsIpfixSessionFullRecord1_t;
            break;
        case DsIpfixSessionHalfRecord0_t:
        case DsIpfixSessionHalfRecord1_t:
            out_tbl_id = (dir == CTC_INGRESS)?DsIpfixSessionHalfRecord0_t:DsIpfixSessionHalfRecord1_t;
            break;
        default:
            out_tbl_id = tbl_id;
            break;
        }
    }
    return out_tbl_id;
}

STATIC int32
_sys_usw_ipfix_get_timer_max_phy_ptr(uint8 lchip, uint32* p_max_phy_ptr)
{
    uint32 ipfix_max_entry_num = 0;

    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &ipfix_max_entry_num));

    p_usw_ipfix_master[lchip]->max_ptr = (DRV_IS_DUET2(lchip)) ? ipfix_max_entry_num : ipfix_max_entry_num / 2;
    *p_max_phy_ptr = (DRV_IS_DUET2(lchip)) ? (ipfix_max_entry_num - 4) : (ipfix_max_entry_num / 2 - 1);
    return CTC_E_NONE;
}


int32 _sys_usw_ipfix_sample_interval_convert(uint8 lchip, sys_ipfix_sample_profile_t* p_profile, uint16* drv_interval )
{
    if(p_profile->mode & 0x01)
    {
        if(DRV_IS_DUET2(lchip))
        {
            uint16 number_cnt = 0;
            if(p_profile->ad_index == 1 || p_profile->ad_index > 3)
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "ipfix random sample can not use profile id 1, line:%d\n", __LINE__);
                return CTC_E_INVALID_PARAM;
            }

            if(p_profile->ad_index == 0 )
            {
                number_cnt = SYS_USW_PROFILE0_NUM_CNT;
            }
            else if(p_profile->ad_index == 2)
            {
                number_cnt = SYS_USW_PROFILE2_NUM_CNT;
            }
            else
            {
                number_cnt = SYS_USW_PROFILE3_NUM_CNT;
            }
            *drv_interval = sys_usw_ipfix_random_data[p_profile->ad_index][number_cnt/p_profile->interval];
        }
        else
        {
            *drv_interval = (1 == p_profile->interval)?4096:(4095/p_profile->interval);
        }
    }
    else
    {
        *drv_interval = p_profile->interval - 1;
    }
    return CTC_E_NONE;
}

STATIC uint32 _sys_usw_ipfix_sample_spool_hask_make(sys_ipfix_sample_profile_t* p_data)
{
    return ctc_hash_caculate(sizeof(sys_ipfix_sample_profile_t)-sizeof(p_data->ad_index), p_data);
}

STATIC bool _sys_usw_ipfix_sample_spool_hash_cmp(sys_ipfix_sample_profile_t* p_ad1, sys_ipfix_sample_profile_t* p_ad2)
{
    uint32 size;
    if (!p_ad1 || !p_ad2)
    {
        return FALSE;
    }

    size = sizeof(sys_ipfix_sample_profile_t)-sizeof(p_ad1->ad_index);
    if (!sal_memcmp(p_ad1, p_ad2, size))
    {
        return TRUE;
    }

    return FALSE;
}

int32
_sys_usw_ipfix_sample_spool_alloc_index(sys_ipfix_sample_profile_t* p_ad, void* user_data)
{
    uint8 lchip = *(uint8*)user_data;
    uint16 ad_index = 0;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        ad_index = (CTC_INGRESS == p_ad->dir) ? p_ad->ad_index : (p_ad->ad_index + MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE));
        CTC_BIT_SET(p_usw_ipfix_master[lchip]->sip_idx_bmp, ad_index);
    }
    else if(CTC_INGRESS == p_ad->dir)
    {
        for(ad_index = 0; ad_index < MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE); ad_index++)
        {
            if(!CTC_IS_BIT_SET(p_usw_ipfix_master[lchip]->sip_idx_bmp, ad_index) && (!DRV_IS_DUET2(lchip) || (!(p_ad->mode&0x01) || ad_index != 1 )))
            {
                CTC_BIT_SET(p_usw_ipfix_master[lchip]->sip_idx_bmp, ad_index);
                p_ad->ad_index = ad_index;
                break;
            }
        }

        if(ad_index == MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"Ingress sample no resource\n");
            return -1;
        }
    }
    else
    {
        for(ad_index = MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE); ad_index < 2*MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE); ad_index++)
        {
            if(!CTC_IS_BIT_SET(p_usw_ipfix_master[lchip]->sip_idx_bmp, ad_index))
            {
                CTC_BIT_SET(p_usw_ipfix_master[lchip]->sip_idx_bmp, ad_index);
                p_ad->ad_index = ad_index-MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE);
                break;
            }
        }
        if(ad_index == 2*MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"Egress sample no resource\n");
            return -1;
        }
    }

    return 0;
}

int32
_sys_usw_ipfix_sample_spool_free_index(sys_ipfix_sample_profile_t* p_ad, void* user_data)
{
    uint8 lchip = *(uint8*)user_data;
    uint16 ad_index;

    CTC_PTR_VALID_CHECK(p_ad);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(CTC_INGRESS == p_ad->dir)
    {
        ad_index = p_ad->ad_index;
    }
    else
    {
        ad_index = p_ad->ad_index + MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE);
    }

    CTC_BIT_UNSET(p_usw_ipfix_master[lchip]->sip_idx_bmp, ad_index);
    return 0;
}

STATIC int32 _sys_usw_ipfix_init_register(uint8 lchip, void* p_global_cfg)
{
    uint32 cmd = 0;
    uint32 max_phy_ptr = 0;
    uint32 value_a = 0;
    ctc_ipfix_global_cfg_t ipfix_cfg;
    uint8 gchip = 0;

    IpfixHashLookupCtl_m ipfix_hash;
    IpeFwdFlowHashCtl_m  ipfix_flow_hash;
    EpeAclQosCtl_m       epe_acl_qos_ctl;
    IpfixAgingTimerCtl_m  aging_timer;
    IpfixEngineCtl_m      ipfix_ctl;
    IpePreLookupFlowCtl_m lookup_ctl;
    FlowAccLfsrCtl_m       flowacclfsrctl;

    sal_memset(&aging_timer, 0, sizeof(IpfixAgingTimerCtl_m));
    sal_memset(&ipfix_ctl, 0, sizeof(IpfixEngineCtl_m));

    sal_memset(&ipfix_hash, 0, sizeof(IpfixHashLookupCtl_m));
    sal_memset(&ipfix_flow_hash, 0, sizeof(ipfix_flow_hash));
    sal_memset(&lookup_ctl, 0, sizeof(IpePreLookupFlowCtl_m));

    sal_memset(&ipfix_cfg, 0, sizeof(ctc_ipfix_global_cfg_t));
    sal_memset(&flowacclfsrctl, 0, sizeof(flowacclfsrctl));

    /*p_global_cfg is NULL, using default config, else using user define */
    sal_memcpy(&ipfix_cfg, p_global_cfg, sizeof(ctc_ipfix_global_cfg_t));

    CTC_ERROR_RETURN(_sys_usw_ipfix_get_timer_max_phy_ptr(lchip,&max_phy_ptr));
    SetIpfixAgingTimerCtl(V, agingMaxPtr_f , &aging_timer, p_usw_ipfix_master[lchip]->max_ptr);
    SetIpfixAgingTimerCtl(V, agingMinPtr_f , &aging_timer, 0);
    SetIpfixAgingTimerCtl(V, agingPhyMaxPtr_f , &aging_timer, max_phy_ptr);
    cmd = DRV_IOW( IpfixAgingTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));
    cmd = DRV_IOW( IpfixAgingTimerCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));
    cmd = DRV_IOW( IpfixAgingTimerCtl1_t, DRV_ENTRY_FLAG);  /* TM */
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));

    SetIpfixEngineCtl(V, bypassUpdateOp_f, &ipfix_ctl, 0);

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    SetIpfixEngineCtl(V, enableRecordMissPktCnt_f , &ipfix_ctl, 1);
    SetIpfixEngineCtl(V, isCpuSetFlowKeyMode_f , &ipfix_ctl, 0);
    SetIpfixEngineCtl(V, ignorTcpClose_f , &ipfix_ctl, 0);   /*spec7.1bug*/
    SetIpfixEngineCtl(V, unknownPktDestIsVlanId_f, &ipfix_ctl, 0);
    SetIpfixEngineCtl(V, ipfixTimeGranularityMode_f, &ipfix_ctl, 1);/*0-8ms; 1-1ms mode;2-16ms;3-1s*/
    SetIpfixEngineCtl(V, myChipId_f, &ipfix_ctl, gchip);
    cmd = DRV_IOW( IpfixEngineCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));
    cmd = DRV_IOW( IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));
    cmd = DRV_IOW( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));

    cmd = DRV_IOR( IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_flow_hash));
    SetIpeFwdFlowHashCtl(V, ipfixDestUseApsGroupId_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, ipfixDestUseEcmpGroupId_f , &ipfix_flow_hash,0);

    SetIpeFwdFlowHashCtl(V, ipfixHashBackToL3V6Type_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, microFlowHashBackToL3V6Type_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, ipfixHashL2L3ForcebackL2Type_f , &ipfix_flow_hash, 0x3);
    SetIpeFwdFlowHashCtl(V, microFlowHashL2L3ForcebackL2Type_f , &ipfix_flow_hash, 0x3);
    SetIpeFwdFlowHashCtl(V, ipfixHashL2L3ForcebackL3Type_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, microFlowHashL2L3ForcebackL3Type_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, mirrorPktEnableMicroflowPolicing_f , &ipfix_flow_hash, 0);
    cmd = DRV_IOW( IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_flow_hash));

    sal_memset(&epe_acl_qos_ctl, 0, sizeof(epe_acl_qos_ctl));
    cmd = DRV_IOR(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_acl_qos_ctl));

    SetEpeAclQosCtl(V, ipfixHashBackToL3V6Type_f, &epe_acl_qos_ctl, 1);
    SetEpeAclQosCtl(V, microFlowHashBackToL3V6Type_f, &epe_acl_qos_ctl, 1);
    SetEpeAclQosCtl(V, ipfixHashL2L3ForcebackL2Type_f, &epe_acl_qos_ctl, 0x3);
    SetEpeAclQosCtl(V, microFlowHashL2L3ForcebackL2Type_f, &epe_acl_qos_ctl, 0x3);
    SetEpeAclQosCtl(V, ipfixHashL2L3ForcebackL3Type_f, &epe_acl_qos_ctl, 1);
    SetEpeAclQosCtl(V, microFlowHashL2L3ForcebackL3Type_f, &epe_acl_qos_ctl, 1);

    cmd = DRV_IOW( EpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_acl_qos_ctl));
    /*set merge global control */
    cmd = DRV_IOR( IpePreLookupFlowCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &lookup_ctl));
    SetIpePreLookupFlowCtl(V, flowVxlanFlowKeyL4UseOuter_f, &lookup_ctl, 1);
    SetIpePreLookupFlowCtl(V, flowGreFlowKeyL4UseOuter_f  , &lookup_ctl, 1);
    SetIpePreLookupFlowCtl(V, flowCapwapFlowKeyL4UseOuter_f,&lookup_ctl, 1);
    cmd = DRV_IOW( IpePreLookupFlowCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &lookup_ctl));

    /* ipfix mirror*/
    value_a = 1;
    cmd = DRV_IOW( IpeFwdCtl_t, IpeFwdCtl_ipfixMirrorPktLogEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

    cmd = DRV_IOW( EpeHeaderEditCtl_t, EpeHeaderEditCtl_ipfixMirrorPktLogEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

    SetFlowAccLfsrCtl(V, igr0RandSeedValue_f, &flowacclfsrctl, SYS_USW_PROFILE0_SEED);
    SetFlowAccLfsrCtl(V, igr2RandSeedValue_f, &flowacclfsrctl, SYS_USW_PROFILE2_SEED);
    SetFlowAccLfsrCtl(V, igr3RandSeedValue_f, &flowacclfsrctl, SYS_USW_PROFILE3_SEED);
    SetFlowAccLfsrCtl(V, egr0RandSeedValue_f, &flowacclfsrctl, SYS_USW_PROFILE0_SEED);
    SetFlowAccLfsrCtl(V, egr2RandSeedValue_f, &flowacclfsrctl, SYS_USW_PROFILE2_SEED);
    SetFlowAccLfsrCtl(V, egr3RandSeedValue_f, &flowacclfsrctl, SYS_USW_PROFILE3_SEED);
    cmd = DRV_IOW(FlowAccLfsrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flowacclfsrctl));

    value_a = 32;
    cmd = DRV_IOW(FlowAccMiscCtl_t, FlowAccMiscCtl_hashCacheClrInterval_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    CTC_ERROR_RETURN(sys_usw_ipfix_set_global_cfg(lchip,&ipfix_cfg));
    return CTC_E_NONE;

}

STATIC int32
sys_usw_ipfix_overflow_isr(uint8 lchip, uint32 intr, void* p_data)
{
    CTC_INTERRUPT_EVENT_FUNC event_cb;
    uint16 tbl_id;
    uint8  gchip;
    ctc_ipfix_event_t event;
    uint32 exceed_threshold;
    uint32 cmd;
    uint8 dir = (intr == SYS_INTR_FUNC_IPFIX_USEAGE_OVERFLOW)? CTC_INGRESS : CTC_EGRESS;

    tbl_id = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? IpfixEngineInterrupt_t:((intr == SYS_INTR_FUNC_IPFIX_USEAGE_OVERFLOW) ? IpfixEngineInterrupt0_t : IpfixEngineInterrupt1_t);
    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_IPFIX_OVERFLOW, &event_cb));
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    cmd = DRV_IOR(tbl_id, IpfixEngineInterrupt_interruptValid_f);

    if (event_cb)
    {
        DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &exceed_threshold);
        event.exceed_threshold = exceed_threshold;
        event.pp_id = lchip - SYS_PP_BASE(lchip);
        event.dir = dir;
        CTC_ERROR_RETURN(event_cb(gchip, &event));
    }
    else
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not initialized \n");
        return CTC_E_NOT_INIT;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_wb_init(uint8 lchip)
{
   ctc_wb_appid_t  appid;
   sal_memset(&appid,0,sizeof(appid));

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER) ;
   appid.entry_num = 1;
   appid.entry_size  = sizeof(sys_wb_ipfix_master_t);
   ctc_wb_add_appid( lchip, &appid);

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XALU_VEC);
   sys_usw_ftm_query_table_entry_num(lchip, DsIpfixConfig1_t, &appid.entry_num);
   appid.entry_size  = sizeof(sys_wb_ipfix_xalu_vec_t);
   ctc_wb_add_appid( lchip, &appid);

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XKEY_VEC) ;
   appid.entry_num = CTC_IPFIX_KEY_HASH_FLEX_END;
   appid.entry_size  = sizeof(sys_wb_ipfix_xkey_vec_t);
   ctc_wb_add_appid( lchip, &appid);

   return 0;
}

STATIC int32
_sys_usw_ipfix_kset_deinit(uint8 lchip)
{
    uint8 loop_i = 0;
    uint8 loop_j = 0;
    if (!p_usw_ipfix_master[lchip]->kset_db)
    {
        return CTC_E_NONE;
    }
    for (loop_i = CTC_INGRESS; loop_i < CTC_BOTH_DIRECTION; loop_i++)
    {
        for (loop_j = 0; loop_j < (CTC_IPFIX_KEY_HASH_FLEX_BASE + 1); loop_j++)
        {
            if (p_usw_ipfix_master[lchip]->kset_db[loop_i][loop_j])
            {
                mem_free(p_usw_ipfix_master[lchip]->kset_db[loop_i][loop_j]);
            }
        }
        if (p_usw_ipfix_master[lchip]->kset_db[loop_i])
        {
            mem_free(p_usw_ipfix_master[lchip]->kset_db[loop_i]);
        }
    }
    if (p_usw_ipfix_master[lchip]->kset_db)
    {
        mem_free(p_usw_ipfix_master[lchip]->kset_db);
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_ipfix_kset_init(uint8 lchip)
{
    uint8 loop_i = 0;
    uint8 loop_j = 0;
    uint32 key_type_bmp[CTC_BOTH_DIRECTION][CTC_B2W_SIZE(CTC_IPFIX_KEY_HASH_FLEX_BASE+1)];
    sys_ipfix_kset_t* p_kset = NULL;

    sal_memset(key_type_bmp, 0, sizeof(key_type_bmp));
    p_usw_ipfix_master[lchip]->kset_db = mem_malloc(MEM_IPFIX_MODULE, CTC_BOTH_DIRECTION*sizeof(void*));
    if (NULL == p_usw_ipfix_master[lchip]->kset_db)
    {
        return CTC_E_NO_MEMORY;
    }
    for (loop_i = CTC_INGRESS; loop_i < CTC_BOTH_DIRECTION; loop_i++)
    {
        p_usw_ipfix_master[lchip]->kset_db[loop_i] = mem_malloc(MEM_IPFIX_MODULE, (CTC_IPFIX_KEY_HASH_FLEX_BASE+1)*sizeof(void*));
        if (NULL == p_usw_ipfix_master[lchip]->kset_db[loop_i])
        {
            return CTC_E_NO_MEMORY;
        }
        for (loop_j = 0; loop_j < (CTC_IPFIX_KEY_HASH_FLEX_BASE+1); loop_j++)
        {
            MALLOC_ZERO(MEM_IPFIX_MODULE, p_kset, sizeof(sys_ipfix_kset_t));
            if (NULL == p_kset)
            {
                return CTC_E_NO_MEMORY;
            }
            p_usw_ipfix_master[lchip]->kset_db[loop_i][loop_j] = p_kset;
        }
    }
    if (DRV_FROM_AT(lchip))
    {
        #include "arctic/sys_at_ipfix_kset.h"
    }

    for (loop_i = CTC_INGRESS; loop_i < CTC_BOTH_DIRECTION; loop_i++)
    {
        for (loop_j = 0; loop_j < (CTC_IPFIX_KEY_HASH_FLEX_BASE+1); loop_j++)
        {
            if (!CTC_BMP_ISSET(key_type_bmp[loop_i], loop_j))
            {
                mem_free(p_usw_ipfix_master[lchip]->kset_db[loop_i][loop_j]);
            }
        }
    }

    return CTC_E_NONE;
}
STATIC int32
_sys_usw_ipfix_free_node_data(void* node_data, void* user_data)
{
    if (node_data)
    {
        mem_free(node_data);
    }
    return CTC_E_NONE;
}

int32
sys_usw_ipfix_init(uint8 lchip, void* p_global_cfg)
{
    uint32 entry_num = 0;
    ctc_spool_t spool;
    uintptr chip_id = lchip;
    int32  ret = CTC_E_NONE;
    uint8 chip_num = 0;

    CTC_PTR_VALID_CHECK(p_global_cfg);

    if (0 == SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_IPFIX))
    {
        return CTC_E_NONE;
    }

    sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &entry_num);
    MCHIP_CAP(SYS_CAP_SPEC_IPFIX_ENTRY_NUM) = entry_num;
    if (!entry_num)
    {   /* no resources */
        return CTC_E_NONE;
    }

    if (p_usw_ipfix_master[lchip])
    {
        return CTC_E_NONE;
    }

    p_usw_ipfix_master[lchip] = (sys_ipfix_master_t*)mem_malloc(MEM_IPFIX_MODULE, sizeof(sys_ipfix_master_t));

    if (NULL == p_usw_ipfix_master[lchip])
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }

    sal_memset(p_usw_ipfix_master[lchip], 0, sizeof(sys_ipfix_master_t));
    sal_mutex_create(&p_usw_ipfix_master[lchip]->p_mutex);

    if((NULL == p_ipfix_cb_mutex) && (g_lchip_num > 1))
    {
        /*for packet rx channel cb, create mux*/
        ret = sal_mutex_create(&p_ipfix_cb_mutex);
        if (ret || !(p_ipfix_cb_mutex))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No resource in ASIC \n");
            ret = CTC_E_NO_MEMORY;
            goto error_proc;
        }
    }

    /*hash spool*/
    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 2;
    spool.block_size = MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE);
    spool.max_count = 2*MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE);
    spool.user_data_size = sizeof(sys_ipfix_sample_profile_t);
    spool.spool_key = (hash_key_fn)_sys_usw_ipfix_sample_spool_hask_make;
    spool.spool_cmp = (hash_cmp_fn)_sys_usw_ipfix_sample_spool_hash_cmp;
    spool.spool_alloc = (spool_alloc_fn)_sys_usw_ipfix_sample_spool_alloc_index;
    spool.spool_free = (spool_free_fn)_sys_usw_ipfix_sample_spool_free_index;
    p_usw_ipfix_master[lchip]->sample_spool = ctc_spool_create(&spool);
    if(NULL == p_usw_ipfix_master[lchip]->sample_spool)
    {
        ret = CTC_E_NO_MEMORY;
        goto error_proc;
    }

    if (MCHIP_IPFIX(lchip)->init_register)
    {
        CTC_ERROR_GOTO(MCHIP_IPFIX(lchip)->init_register(lchip, p_global_cfg), ret, error_proc);
    }
    else
    {
        CTC_ERROR_GOTO(_sys_usw_ipfix_init_register(lchip, p_global_cfg), ret, error_proc);
    }

    if (!p_usw_ipfix_master[lchip]->ipfix_cb)
    {
        sys_usw_ipfix_register_cb(lchip, _sys_usw_ipfix_process_isr, (void*)chip_id);
    }

    CTC_ERROR_GOTO(sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_IPFIX,sys_usw_ipfix_ftm_cb), ret, error_proc);
    CTC_ERROR_GOTO(sys_usw_dma_register_cb(SYS_CHIP_CONVERT_DMA(lchip), SYS_DMA_CB_TYPE_IPFIX,
        sys_usw_ipfix_sync_data), ret, error_proc);
    CTC_ERROR_GOTO(SYS_CB_REGISTER(lchip, SYS_CB_IPFIX_DFT_CFG_TO_NPM, sys_usw_ipfix_npm_im_flow_en), ret, error_proc);

    CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_IPFIX_USEAGE_OVERFLOW, sys_usw_ipfix_overflow_isr), ret, error_proc);
    CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(SYS_CHIP_CONVERT(lchip), SYS_INTR_FUNC_EPE_IPFIX_USEAGE_OVERFLOW, sys_usw_ipfix_overflow_isr), ret, error_proc);

    if (DRV_FROM_AT(lchip))
    {
        if (lchip == SYS_PP_BASE(lchip))
        {
            p_usw_ipfix_master[lchip]->flex_key_vec = ctc_vector_init(CTC_VEC_BLOCK_NUM(SYS_IPFIX_FLEX_KEY_VEC_SIZE, SYS_IPFIX_FLEX_KEY_VEC_BLOCK_SIZE), SYS_IPFIX_FLEX_KEY_VEC_BLOCK_SIZE);
            if (NULL == p_usw_ipfix_master[lchip]->flex_key_vec)
            {
                ret = CTC_E_INIT_FAIL;
                goto error_proc;
            }
            CTC_ERROR_GOTO(_sys_usw_ipfix_kset_init(lchip), ret, free_kset);
        }
        else
        {
            p_usw_ipfix_master[lchip]->flex_key_vec = p_usw_ipfix_master[SYS_PP_BASE(lchip)]->flex_key_vec;
            p_usw_ipfix_master[lchip]->kset_db = p_usw_ipfix_master[SYS_PP_BASE(lchip)]->kset_db;

        }
    }
    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_IPFIX, sys_usw_ipfix_dump_db), ret, error_proc);
    if ( CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_GOTO(sys_usw_ipfix_wb_restore(lchip), ret, error_proc);
    }
    if (CTC_WB_ENABLE(lchip))
    {
        _sys_usw_ipfix_wb_init(lchip);
    }
    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_IPFIX,SYS_WB_APPID_IPFIX_SUBID_MAX, sys_usw_ipfix_wb_sync), ret, error_proc);
    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_IPFIX);
    if (MCHIP_IPFIX(lchip)->cb_init)
    {
        CTC_ERROR_GOTO(MCHIP_IPFIX(lchip)->cb_init(lchip), ret, error_proc);
    }
    return CTC_E_NONE;

free_kset:
        _sys_usw_ipfix_kset_deinit(lchip);
error_proc:
    if(p_usw_ipfix_master[lchip])
    {
        if(p_usw_ipfix_master[lchip]->sample_spool)
        {
            ctc_spool_free(p_usw_ipfix_master[lchip]->sample_spool);
        }

        sys_usw_chip_get_active_num(&chip_num);
        if (p_ipfix_cb_mutex && (1 == chip_num))
        {
            sal_mutex_destroy(p_ipfix_cb_mutex);
            p_ipfix_cb_mutex = NULL;
        }

        if(p_usw_ipfix_master[lchip]->p_mutex)
        {
            sal_mutex_destroy(p_usw_ipfix_master[lchip]->p_mutex);
        }
        if (p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS])
        {
            ctc_spool_free(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS]);
        }
        if (p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS])
        {
            ctc_spool_free(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS]);
        }
        if (p_usw_ipfix_master[lchip]->xalu_spool)
        {
            ctc_spool_free(p_usw_ipfix_master[lchip]->xalu_spool);
        }
        if (p_usw_ipfix_master[lchip]->xalu_vec)
        {
            ctc_vector_release(p_usw_ipfix_master[lchip]->xalu_vec);
        }
        if (p_usw_ipfix_master[lchip]->flex_key_vec && !SYS_VCHIP_PP_IS_NOT_BASE(lchip))
        {
            ctc_vector_release(p_usw_ipfix_master[lchip]->flex_key_vec);
        }
        else
        {
            p_usw_ipfix_master[lchip]->flex_key_vec = NULL;
        }

        mem_free(p_usw_ipfix_master[lchip]);
    }
    return ret;

}
int32
sys_usw_ipfix_deinit(uint8 lchip)
{
    IpfixEngineMmuCtl_m mmu_ctl;
    uint8 chip_num = 0;

    LCHIP_CHECK(lchip);

    if (NULL == p_usw_ipfix_master[lchip])
    {
        return CTC_E_NONE;
    }

    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_IPFIX,NULL);
    sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_IPFIX, NULL);
    SYS_CB_REGISTER(lchip, SYS_CB_IPFIX_DFT_CFG_TO_NPM, NULL);
    sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_IPFIX_USEAGE_OVERFLOW, NULL);
    sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_IPFIX, NULL);
    sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_IPFIX,0, NULL);

    ctc_spool_free(p_usw_ipfix_master[lchip]->sample_spool);
    if (p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS])
    {
        ctc_spool_free(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS]);
    }
    if (p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS])
    {
        ctc_spool_free(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS]);
    }
    if (p_usw_ipfix_master[lchip]->xalu_spool)
    {
        ctc_spool_free(p_usw_ipfix_master[lchip]->xalu_spool);
    }
    if (p_usw_ipfix_master[lchip]->xalu_vec)
    {
        ctc_vector_traverse(p_usw_ipfix_master[lchip]->xalu_vec, (vector_traversal_fn)_sys_usw_ipfix_free_node_data, NULL);
        ctc_vector_release(p_usw_ipfix_master[lchip]->xalu_vec);
    }
    if (p_usw_ipfix_master[lchip]->flex_key_vec && !SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        ctc_vector_traverse(p_usw_ipfix_master[lchip]->flex_key_vec, (vector_traversal_fn)_sys_usw_ipfix_free_node_data, NULL);
        ctc_vector_release(p_usw_ipfix_master[lchip]->flex_key_vec);
    }
    else
    {
        p_usw_ipfix_master[lchip]->flex_key_vec = NULL;
    }
    if (!SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        _sys_usw_ipfix_kset_deinit(lchip);
        mem_free(p_usw_ipfix_master[lchip]->cb_buf);
    }
    else
    {
        p_usw_ipfix_master[lchip]->kset_db = NULL;
    }
    sal_mutex_destroy(p_usw_ipfix_master[lchip]->p_mutex);
    sys_usw_chip_get_active_num(&chip_num);
    if (p_ipfix_cb_mutex && (1 == chip_num))
    {
        sal_mutex_destroy(p_ipfix_cb_mutex);
        p_ipfix_cb_mutex = NULL;
    }
    mem_free(p_usw_ipfix_master[lchip]);
    sal_memset(&mmu_ctl, 0, sizeof(mmu_ctl));
    return CTC_E_NONE;
}
int32
_sys_usw_ipfix_set_l2_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL2HashFieldSelect_m  hash_field;
    uint8 global_port_type = 0;
    uint32 cmd = 0;

    sal_memset(&hash_field, 0, sizeof(IpfixL2HashFieldSelect_m));

    if ((!DRV_FROM_TMM(lchip)) && ((field_sel->u.mac.mac_sa && field_sel->u.mac.src_cid) || (field_sel->u.mac.mac_da && field_sel->u.mac.dst_cid)))
    {
        return CTC_E_PARAM_CONFLICT;
    }
    SetIpfixL2HashFieldSelect(V, cfiEn_f, &hash_field, field_sel->u.mac.cfi);
    SetIpfixL2HashFieldSelect(V, cosEn_f, &hash_field, field_sel->u.mac.cos);
    SetIpfixL2HashFieldSelect(V, vlanIdEn_f, &hash_field, field_sel->u.mac.vlan_id);
    SetIpfixL2HashFieldSelect(V, etherTypeEn_f, &hash_field, field_sel->u.mac.eth_type);
    SetIpfixL2HashFieldSelect(V, macDaEn_f, &hash_field, field_sel->u.mac.mac_da);
    SetIpfixL2HashFieldSelect(V, macSaEn_f, &hash_field, field_sel->u.mac.mac_sa);
    SetIpfixL2HashFieldSelect(V, macSaUseSrcCategoryId_f, &hash_field, field_sel->u.mac.src_cid);
    SetIpfixL2HashFieldSelect(V, macDaUseDstCategoryId_f, &hash_field, field_sel->u.mac.dst_cid);
    SetIpfixL2HashFieldSelect(V, srcCategoryIdEn_f, &hash_field, field_sel->u.mac.src_cid);
    SetIpfixL2HashFieldSelect(V, dstCategoryIdEn_f, &hash_field, field_sel->u.mac.dst_cid);
    SetIpfixL2HashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.mac.profile_id);

    SetIpfixL2HashFieldSelect(V, scfiEn_f, &hash_field, field_sel->u.mac.cfi);/*TMM...*/
    SetIpfixL2HashFieldSelect(V, scosEn_f, &hash_field, field_sel->u.mac.cos);/*TMM...*/
    SetIpfixL2HashFieldSelect(V, svlanIdEn_f, &hash_field, field_sel->u.mac.vlan_id);/*TMM...*/
    SetIpfixL2HashFieldSelect(V, ccfiEn_f, &hash_field, field_sel->u.mac.ctag_cfi);/*TMM...*/
    SetIpfixL2HashFieldSelect(V, ccosEn_f, &hash_field, field_sel->u.mac.ctag_cos);/*TMM...*/
    SetIpfixL2HashFieldSelect(V, cvlanIdEn_f, &hash_field, field_sel->u.mac.ctag_vlan);/*TMM...*/
    SetIpfixL2HashFieldSelect(V, vsiIdEn_f, &hash_field, field_sel->u.mac.fid);/*TMM...*/
    if (DRV_FROM_AT(lchip))
    {
        SetIpfixL2HashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);/*AT...*/
    }
    if (field_sel->u.mac.vlan_id || field_sel->u.mac.cfi || field_sel->u.mac.cos)
    {
        SetIpfixL2HashFieldSelect(V, vlanIdValidEn_f, &hash_field, 1);
        SetIpfixL2HashFieldSelect(V, svlanIdValidEn_f, &hash_field, 1);/*TMM...*/
    }
    if (field_sel->u.mac.ctag_vlan || field_sel->u.mac.ctag_cfi || field_sel->u.mac.ctag_cos)/*TMM...*/
    {
        SetIpfixL2HashFieldSelect(V, cvlanIdValidEn_f, &hash_field, 1);/*TMM...*/
    }

    if (field_sel->u.mac.gport)
    {
        global_port_type = 1;
    }
    else if (field_sel->u.mac.logic_port)
    {
        global_port_type = 2;
    }
    else if (field_sel->u.mac.metadata)
    {
        if (DRV_IS_DUET2(lchip))
        {
            global_port_type = 3;
        }
        else
        {
            global_port_type = 4;
        }
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixL2HashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);

    cmd = DRV_IOW( IpfixL2HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL2HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL2HashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    return CTC_E_NONE;

}

int32
_sys_usw_ipfix_set_ipv4_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL3Ipv4HashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint32 ip_prefix_len = 0;
    uint8 global_port_type = 0;

    uint8 is_gre = !!field_sel->u.ipv4.gre_key;
    uint8 is_nvgre = !!field_sel->u.ipv4.nvgre_key;
    uint8 is_icmp = field_sel->u.ipv4.icmp_code || field_sel->u.ipv4.icmp_type;
    uint8 is_igmp = !!field_sel->u.ipv4.igmp_type;
    uint8 is_vxlan = !!field_sel->u.ipv4.vxlan_vni;
    uint8 is_l4_port = field_sel->u.ipv4.l4_src_port || field_sel->u.ipv4.l4_dst_port;
    uint8 is_protocol = !!field_sel->u.ipv4.ip_protocol;

    uint8 is_vrfid = !!field_sel->u.ipv4.vrfid;
    uint8 is_ip_identification = !!field_sel->u.ipv4.ip_identification;
    uint8 is_ip_pkt_len = !!field_sel->u.ipv4.ip_pkt_len;

    if (field_sel->u.ipv4.l4_sub_type)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " API or some feature is not supported \n");
        return CTC_E_NOT_SUPPORT;
    }

    if ((!DRV_FROM_TMM(lchip)) && ((field_sel->u.ipv4.ip_sa && field_sel->u.ipv4.src_cid) || (field_sel->u.ipv4.ip_da && field_sel->u.ipv4.dst_cid)))
    {
        return CTC_E_PARAM_CONFLICT;
    }

    if(is_protocol)
    {
        if((is_gre + is_nvgre +is_vxlan)>1)
        {
            return CTC_E_PARAM_CONFLICT;
        }
        if((is_gre || is_nvgre || is_vxlan)&&(is_icmp||is_l4_port||is_igmp))
        {
             return CTC_E_PARAM_CONFLICT;
        }
    }
    else
    {
        if((is_gre + is_nvgre + is_icmp + is_igmp + is_vxlan + is_l4_port) > 1)
        {
             return CTC_E_PARAM_CONFLICT;
        }
    }

    if ((DRV_FROM_TMM(lchip)) && (is_vrfid + is_ip_identification + is_ip_pkt_len > 1))
    {
        return CTC_E_PARAM_CONFLICT;
    }

    sal_memset(&hash_field, 0, sizeof(IpfixL3Ipv4HashFieldSelect_m));
    if (DRV_FROM_AT(lchip))
    {
        SetIpfixL3Ipv4HashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);/*AT...*/
    }
    /*share field mode*/
    if (!DRV_FROM_TMM(lchip))
    {
        if ((field_sel->u.ipv4.ip_frag || field_sel->u.ipv4.tcp_flags) &&
            !(field_sel->u.ipv4.ip_identification || field_sel->u.ipv4.ip_pkt_len || field_sel->u.ipv4.vrfid))
        {
            SetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field, 0);
            SetIpfixL3Ipv4HashFieldSelect(V, u1_g1_fragInfoEn_f, &hash_field, field_sel->u.ipv4.ip_frag);
            SetIpfixL3Ipv4HashFieldSelect(V, u1_g1_tcpFlagsEn_f, &hash_field, field_sel->u.ipv4.tcp_flags);
        }
        else if (field_sel->u.ipv4.ip_identification && !(field_sel->u.ipv4.ip_frag || field_sel->u.ipv4.tcp_flags
            || field_sel->u.ipv4.ip_pkt_len  || field_sel->u.ipv4.vrfid))
        {
            SetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field, 1);
            SetIpfixL3Ipv4HashFieldSelect(V, u1_g2_ipIdentificationEn_f, &hash_field, field_sel->u.ipv4.ip_identification);
        }
        else if (field_sel->u.ipv4.ip_pkt_len && !(field_sel->u.ipv4.tcp_flags || field_sel->u.ipv4.ip_identification
            || field_sel->u.ipv4.vrfid))
        {
            SetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field, 2);
            SetIpfixL3Ipv4HashFieldSelect(V, u1_g3_fragInfoEn_f, &hash_field, field_sel->u.ipv4.ip_frag);
            SetIpfixL3Ipv4HashFieldSelect(V, u1_g3_ipLengthEn_f, &hash_field, field_sel->u.ipv4.ip_pkt_len);
        }
        else if (field_sel->u.ipv4.vrfid && !(field_sel->u.ipv4.tcp_flags || field_sel->u.ipv4.ip_identification ||
            field_sel->u.ipv4.ip_pkt_len))
        {
            SetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field, 3);
            SetIpfixL3Ipv4HashFieldSelect(V, u1_g4_fragInfoEn_f, &hash_field, field_sel->u.ipv4.ip_frag);
            SetIpfixL3Ipv4HashFieldSelect(V, u1_g4_vrfIdEn_f, &hash_field, field_sel->u.ipv4.vrfid);
        }
        else if (field_sel->u.ipv4.ip_frag || field_sel->u.ipv4.tcp_flags || field_sel->u.ipv4.ip_identification
            || field_sel->u.ipv4.ip_pkt_len || field_sel->u.ipv4.vrfid)
        {
            return CTC_E_PARAM_CONFLICT;
        }
    }
    else
    {
        if (field_sel->u.ipv4.vrfid)
        {
            SetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field, 0);
            SetIpfixL3Ipv4HashFieldSelect(V, vrfIdEn_f, &hash_field, field_sel->u.ipv4.vrfid);
        }
        else if (field_sel->u.ipv4.ip_identification)
        {
            SetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field, 1);
            SetIpfixL3Ipv4HashFieldSelect(V, ipIdentificationEn_f, &hash_field, field_sel->u.ipv4.ip_identification);
        }
        else if (field_sel->u.ipv4.ip_pkt_len)
        {
            SetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field, 2);
            SetIpfixL3Ipv4HashFieldSelect(V, ipLengthEn_f, &hash_field, field_sel->u.ipv4.ip_pkt_len);
        }
    }

    SetIpfixL3Ipv4HashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.ipv4.profile_id);
    SetIpfixL3Ipv4HashFieldSelect(V, dscpEn_f, &hash_field, field_sel->u.ipv4.dscp);
    SetIpfixL3Ipv4HashFieldSelect(V, ecnEn_f, &hash_field, field_sel->u.ipv4.ecn);
    SetIpfixL3Ipv4HashFieldSelect(V, ttlEn_f, &hash_field, field_sel->u.ipv4.ttl);
    SetIpfixL3Ipv4HashFieldSelect(V, icmpOpcodeEn_f, &hash_field, field_sel->u.ipv4.icmp_code);
    SetIpfixL3Ipv4HashFieldSelect(V, icmpTypeEn_f, &hash_field, field_sel->u.ipv4.icmp_type);
    SetIpfixL3Ipv4HashFieldSelect(V, igmpTypeEn_f, &hash_field, field_sel->u.ipv4.igmp_type);
    SetIpfixL3Ipv4HashFieldSelect(V, greKeyEn_f, &hash_field, field_sel->u.ipv4.gre_key);
    SetIpfixL3Ipv4HashFieldSelect(V, nvgreVsidEn_f, &hash_field, field_sel->u.ipv4.nvgre_key);
    SetIpfixL3Ipv4HashFieldSelect(V, ignorVxlan_f, &hash_field, (field_sel->u.ipv4.vxlan_vni)? 0 : 1);

    SetIpfixL3Ipv4HashFieldSelect(V, vsiIdEn_f, &hash_field, field_sel->u.ipv4.fid);/*TMM...*/
    SetIpfixL3Ipv4HashFieldSelect(V, tcpBidiFlowSessionEn_f, &hash_field, field_sel->u.ipv4.sym_session_en);/*TMM...*/
    SetIpfixL3Ipv4HashFieldSelect(V, fragInfoEn_f , &hash_field, field_sel->u.ipv4.ip_frag);/*TMM...*/
    SetIpfixL3Ipv4HashFieldSelect(V, tcpFlagsEn_f, &hash_field, field_sel->u.ipv4.tcp_flags);/*TMM...*/

    if (field_sel->u.ipv4.ip_da)
    {
        IPFIX_IPV4_MASK_LEN_CHECK(field_sel->u.ipv4.ip_da_mask);
        ip_prefix_len = field_sel->u.ipv4.ip_da_mask - 1 ;

        SetIpfixL3Ipv4HashFieldSelect(V,  ipDaPrefixLength_f, &hash_field, ip_prefix_len);
        SetIpfixL3Ipv4HashFieldSelect(V,  ipDaEn_f, &hash_field, 1);
    }

    if (field_sel->u.ipv4.ip_sa)
    {
        IPFIX_IPV4_MASK_LEN_CHECK(field_sel->u.ipv4.ip_sa_mask);
        ip_prefix_len = field_sel->u.ipv4.ip_sa_mask - 1;

        SetIpfixL3Ipv4HashFieldSelect(V,  ipSaPrefixLength_f, &hash_field, ip_prefix_len);
        SetIpfixL3Ipv4HashFieldSelect(V,  ipSaEn_f, &hash_field, 1);
    }
    SetIpfixL3Ipv4HashFieldSelect(V, ipSaUseSrcCategoryId_f, &hash_field, field_sel->u.ipv4.src_cid);
    SetIpfixL3Ipv4HashFieldSelect(V, ipDaUseDstCategoryId_f, &hash_field, field_sel->u.ipv4.dst_cid);
    SetIpfixL3Ipv4HashFieldSelect(V, srcCategoryIdEn_f, &hash_field, field_sel->u.ipv4.src_cid);
    SetIpfixL3Ipv4HashFieldSelect(V, dstCategoryIdEn_f, &hash_field, field_sel->u.ipv4.dst_cid);
    SetIpfixL3Ipv4HashFieldSelect(V, vxlanVniEn_f, &hash_field, field_sel->u.ipv4.vxlan_vni);
    SetIpfixL3Ipv4HashFieldSelect(V, l4DestPortEn_f, &hash_field, field_sel->u.ipv4.l4_dst_port);
    SetIpfixL3Ipv4HashFieldSelect(V, l4SourcePortEn_f, &hash_field, field_sel->u.ipv4.l4_src_port);
    SetIpfixL3Ipv4HashFieldSelect(V, layer3HeaderProtocolEn_f, &hash_field, field_sel->u.ipv4.ip_protocol);
    SetIpfixL3Ipv4HashFieldSelect(V, isVxlanEn_f , &hash_field, field_sel->u.ipv4.vxlan_vni);

    if (field_sel->u.ipv4.gport)
    {
        global_port_type = 1;
    }
    else if (field_sel->u.ipv4.logic_port)
    {
        global_port_type = 2;
    }
    else if (field_sel->u.ipv4.metadata)
    {
        if (DRV_IS_DUET2(lchip))
        {
            global_port_type = 3;
        }
        else
        {
            global_port_type = 4;
        }
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixL3Ipv4HashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);
    cmd = DRV_IOW( IpfixL3Ipv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL3Ipv4HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL3Ipv4HashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_set_ipv6_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL3Ipv6HashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint32 ip_prefix_len = 0;
    uint8 global_port_type = 0;

    uint8 is_gre = !!field_sel->u.ipv6.gre_key;
    uint8 is_nvgre = !!field_sel->u.ipv6.nvgre_key;
    uint8 is_icmp = field_sel->u.ipv6.icmp_code || field_sel->u.ipv6.icmp_type;
    uint8 is_igmp = !!field_sel->u.ipv6.igmp_type;
    uint8 is_vxlan = !!field_sel->u.ipv6.vxlan_vni;
    uint8 is_l4_port = field_sel->u.ipv6.l4_src_port || field_sel->u.ipv6.l4_dst_port;
    uint8 is_capwap = field_sel->u.ipv6.wlan_ctl_packet || field_sel->u.ipv6.wlan_radio_id || field_sel->u.ipv6.wlan_radio_mac;

    uint8 is_mode0 = (field_sel->u.ipv6.ip_sa && (field_sel->u.ipv6.ip_sa_mask > 64)) || \
                                                            (field_sel->u.ipv6.ip_da && (field_sel->u.ipv6.ip_da_mask > 64));
    uint8 is_mode1 = (field_sel->u.ipv6.flow_label || field_sel->u.ipv6.ttl || field_sel->u.ipv6.ecn ||
                                            field_sel->u.ipv6.ip_frag || field_sel->u.ipv6.aware_tunnel_info_en ||
                                            field_sel->u.ipv6.src_cid || field_sel->u.ipv6.dst_cid || field_sel->u.ipv6.tcp_flags );
    uint8 is_protocol = !!field_sel->u.ipv6.ip_protocol;


    if(DRV_FROM_TMM(lchip))
    {
        is_mode0 = 0;
        is_mode1 = 0;
    }
    if((field_sel->u.ipv6.l4_type || field_sel->u.ipv6.l4_sub_type)||(DRV_FROM_TMM(lchip)&&is_capwap))
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " API or some feature is not supported \n");
        return CTC_E_NOT_SUPPORT;
    }

    if (field_sel->u.ipv6.aware_tunnel_info_en)
    {
        if ((is_gre + is_nvgre + is_vxlan + is_capwap) > 1 )
        {
            return CTC_E_PARAM_CONFLICT;
        }

        if ((is_icmp + is_igmp + is_l4_port) > 1 )
        {
            return CTC_E_PARAM_CONFLICT;
        }
    }
    else if(is_protocol)
    {
        if((is_gre + is_nvgre +is_igmp+is_vxlan) > 1)
        {
            return CTC_E_PARAM_CONFLICT;
        }
        if((is_gre || is_nvgre ||is_igmp||is_vxlan)&&(is_icmp||is_l4_port))
        {
             return CTC_E_PARAM_CONFLICT;
        }
    }
    else
    {
        if((is_gre + is_nvgre + is_igmp +is_icmp + is_l4_port+is_vxlan) > 1)
        {
             return CTC_E_PARAM_CONFLICT;
        }
    }

    if(is_mode0 && is_mode1)
    {
        return CTC_E_PARAM_CONFLICT;
    }

    if(is_capwap && !field_sel->u.ipv6.aware_tunnel_info_en)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "capwap info must use merge key\n");
        return CTC_E_NOT_SUPPORT;
    }

    sal_memset(&hash_field, 0, sizeof(IpfixL3Ipv6HashFieldSelect_m));
    if(is_mode1)
    {
        SetIpfixL3Ipv6HashFieldSelect(V, ipAddressMode_f, &hash_field, 1);
    }

    SetIpfixL3Ipv6HashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.ipv6.profile_id);
    SetIpfixL3Ipv6HashFieldSelect(V, dscpEn_f, &hash_field, field_sel->u.ipv6.dscp);
    SetIpfixL3Ipv6HashFieldSelect(V, icmpOpcodeEn_f, &hash_field, field_sel->u.ipv6.icmp_code);
    SetIpfixL3Ipv6HashFieldSelect(V, icmpTypeEn_f, &hash_field, field_sel->u.ipv6.icmp_type);
    SetIpfixL3Ipv6HashFieldSelect(V, igmpTypeEn_f, &hash_field, field_sel->u.ipv6.igmp_type);
    SetIpfixL3Ipv6HashFieldSelect(V, l4DestPortEn_f, &hash_field, field_sel->u.ipv6.l4_dst_port);
    SetIpfixL3Ipv6HashFieldSelect(V, l4SourcePortEn_f, &hash_field, field_sel->u.ipv6.l4_src_port);
    SetIpfixL3Ipv6HashFieldSelect(V, layer3HeaderProtocolEn_f, &hash_field, field_sel->u.ipv6.ip_protocol);
    if(!field_sel->u.ipv6.aware_tunnel_info_en)
    {
        SetIpfixL3Ipv6HashFieldSelect(V, greKeyEn_f, &hash_field, field_sel->u.ipv6.gre_key);
        SetIpfixL3Ipv6HashFieldSelect(V, nvgreVsidEn_f, &hash_field, field_sel->u.ipv6.nvgre_key);
        SetIpfixL3Ipv6HashFieldSelect(V, vxlanVniEn_f, &hash_field, field_sel->u.ipv6.vxlan_vni);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyMode_f, &hash_field, 0);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_ignorVxlan_f, &hash_field, !(field_sel->u.ipv6.vxlan_vni));
    }
    else
    {
        SetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyMode_f, &hash_field, 1);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_ignorCapwap_f, &hash_field, !is_capwap);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_ignorGreWithKey_f, &hash_field, !(field_sel->u.ipv6.gre_key + field_sel->u.ipv6.nvgre_key));
        SetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyVxlanVniEn_f, &hash_field, field_sel->u.ipv6.vxlan_vni);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyNvgreVsidEn_f, &hash_field, field_sel->u.ipv6.nvgre_key);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyGreKeyEn_f, &hash_field, field_sel->u.ipv6.gre_key);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyCapwapRadioMacEn_f, &hash_field, field_sel->u.ipv6.wlan_radio_mac);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyCapwapRidEn_f, &hash_field, field_sel->u.ipv6.wlan_radio_id);
        SetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyCapwapControlPktEn_f, &hash_field, field_sel->u.ipv6.wlan_ctl_packet);
    }
    if (field_sel->u.ipv6.ip_da)
    {
        IPFIX_IPV6_MASK_LEN_CHECK(field_sel->u.ipv6.ip_da_mask);
        ip_prefix_len = (field_sel->u.ipv6.ip_da_mask>>2)-1;
        SetIpfixL3Ipv6HashFieldSelect(V, ipDaPrefixLength_f, &hash_field, ip_prefix_len);
        SetIpfixL3Ipv6HashFieldSelect(V, ipDaEn_f, &hash_field, 1);
    }

    if (field_sel->u.ipv6.ip_sa)
    {
        IPFIX_IPV6_MASK_LEN_CHECK(field_sel->u.ipv6.ip_sa_mask);
        ip_prefix_len = (field_sel->u.ipv6.ip_sa_mask>>2)-1;
        SetIpfixL3Ipv6HashFieldSelect(V, ipSaPrefixLength_f, &hash_field, ip_prefix_len);
        SetIpfixL3Ipv6HashFieldSelect(V, ipSaEn_f, &hash_field, 1);
    }

    SetIpfixL3Ipv6HashFieldSelect(V, g1_srcCategoryIdEn_f, &hash_field, field_sel->u.ipv6.src_cid);
    SetIpfixL3Ipv6HashFieldSelect(V, g1_dstCategoryIdEn_f, &hash_field, field_sel->u.ipv6.dst_cid);
    SetIpfixL3Ipv6HashFieldSelect(V, g1_ipv6FlowLabelEn_f, &hash_field, field_sel->u.ipv6.flow_label);
    SetIpfixL3Ipv6HashFieldSelect(V, g1_ttlEn_f, &hash_field, field_sel->u.ipv6.ttl);
    SetIpfixL3Ipv6HashFieldSelect(V, g1_ecnEn_f, &hash_field, field_sel->u.ipv6.ecn);
    SetIpfixL3Ipv6HashFieldSelect(V, g1_fragInfoEn_f, &hash_field, field_sel->u.ipv6.ip_frag);
    SetIpfixL3Ipv6HashFieldSelect(V, g1_tcpFlagsEn_f, &hash_field, field_sel->u.ipv6.tcp_flags);

    SetIpfixL3Ipv6HashFieldSelect(V, vsiIdEn_f, &hash_field, field_sel->u.ipv6.fid);/*TMM...*/
    SetIpfixL3Ipv6HashFieldSelect(V, tcpBidiFlowSessionEn_f, &hash_field, field_sel->u.ipv6.sym_session_en);/*TMM...*/
    SetIpfixL3Ipv6HashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);/*AT...*/
    SetIpfixL3Ipv6HashFieldSelect(V, vrfIdEn_f, &hash_field, field_sel->u.ipv6.vrfid);/*AT...*/

    if(field_sel->u.ipv6.gport)
    {
        global_port_type = 1;
    }
    else if(field_sel->u.ipv6.logic_port)
    {
        global_port_type = 2;
    }
    else if(field_sel->u.ipv6.metadata)
    {
        if (DRV_IS_DUET2(lchip))
        {
            global_port_type = 3;
        }
        else
        {
            global_port_type = 4;
        }
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixL3Ipv6HashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);

    cmd = DRV_IOW( IpfixL3Ipv6HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL3Ipv6HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL3Ipv6HashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_set_mpls_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL3MplsHashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint8 global_port_type = 0;
    sal_memset(&hash_field, 0, sizeof(IpfixL3MplsHashFieldSelect_m));
    if (DRV_FROM_AT(lchip))
    {
        SetIpfixL3MplsHashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);/*AT...*/
    }
    SetIpfixL3MplsHashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.mpls.profile_id);
    SetIpfixL3MplsHashFieldSelect(V,  labelNumEn_f      , &hash_field, field_sel->u.mpls.label_num);
    SetIpfixL3MplsHashFieldSelect(V,  mplsExp0En_f      , &hash_field, field_sel->u.mpls.mpls_label0_exp);
    SetIpfixL3MplsHashFieldSelect(V,  mplsExp1En_f      , &hash_field, field_sel->u.mpls.mpls_label1_exp);
    SetIpfixL3MplsHashFieldSelect(V,  mplsExp2En_f      , &hash_field, field_sel->u.mpls.mpls_label2_exp);
    SetIpfixL3MplsHashFieldSelect(V, mplsLabel0En_f    , &hash_field, field_sel->u.mpls.mpls_label0_label);
    SetIpfixL3MplsHashFieldSelect(V, mplsLabel1En_f    , &hash_field, field_sel->u.mpls.mpls_label1_label);
    SetIpfixL3MplsHashFieldSelect(V, mplsLabel2En_f    , &hash_field, field_sel->u.mpls.mpls_label2_label);
    SetIpfixL3MplsHashFieldSelect(V, mplsSbit0En_f     , &hash_field, field_sel->u.mpls.mpls_label0_s);
    SetIpfixL3MplsHashFieldSelect(V, mplsSbit1En_f     , &hash_field, field_sel->u.mpls.mpls_label1_s);
    SetIpfixL3MplsHashFieldSelect(V, mplsSbit2En_f     , &hash_field, field_sel->u.mpls.mpls_label2_s);
    SetIpfixL3MplsHashFieldSelect(V, mplsTtl0En_f      , &hash_field, field_sel->u.mpls.mpls_label0_ttl);
    SetIpfixL3MplsHashFieldSelect(V, mplsTtl1En_f      , &hash_field, field_sel->u.mpls.mpls_label1_ttl);
    SetIpfixL3MplsHashFieldSelect(V, mplsTtl2En_f      , &hash_field, field_sel->u.mpls.mpls_label2_ttl);

    SetIpfixL3MplsHashFieldSelect(V, vsiIdEn_f      , &hash_field, field_sel->u.mpls.fid);/*TMM...*/

    if (field_sel->u.mpls.gport)
    {
        global_port_type = 1;
    }
    else if (field_sel->u.mpls.logic_port)
    {
        global_port_type = 2;
    }
    else if (field_sel->u.mpls.metadata)
    {
        if (DRV_IS_DUET2(lchip))
        {
            global_port_type = 3;
        }
        else
        {
            global_port_type = 4;
        }
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixL3MplsHashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);
    cmd = DRV_IOW( IpfixL3MplsHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL3MplsHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL3MplsHashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_set_l2l3_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL2L3HashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint32 ip_prefix_len = 0;
    uint8 global_port_type = 0;
    uint8 is_capwap = field_sel->u.l2_l3.wlan_ctl_packet || field_sel->u.l2_l3.wlan_radio_id || field_sel->u.l2_l3.wlan_radio_mac;
    uint8 is_gre = !!field_sel->u.l2_l3.gre_key;
    uint8 is_nvgre = !!field_sel->u.l2_l3.nvgre_key;
    uint8 is_icmp = field_sel->u.l2_l3.icmp_code || field_sel->u.l2_l3.icmp_type;
    uint8 is_igmp = !!field_sel->u.l2_l3.igmp_type;
    uint8 is_vxlan = !!field_sel->u.l2_l3.vxlan_vni;
    uint8 is_l4_port = field_sel->u.l2_l3.l4_src_port || field_sel->u.l2_l3.l4_dst_port || field_sel->u.l2_l3.tcp_flags;
    uint8 is_protocol = !!field_sel->u.l2_l3.ip_protocol;

    uint8 is_mpls = field_sel->u.l2_l3.label_num || \
                    field_sel->u.l2_l3.mpls_label0_exp || \
                    field_sel->u.l2_l3.mpls_label1_exp || \
                    field_sel->u.l2_l3.mpls_label2_exp || \
                    field_sel->u.l2_l3.mpls_label0_label || \
                    field_sel->u.l2_l3.mpls_label1_label || \
                    field_sel->u.l2_l3.mpls_label2_label || \
                    field_sel->u.l2_l3.mpls_label0_s || \
                    field_sel->u.l2_l3.mpls_label1_s || \
                    field_sel->u.l2_l3.mpls_label2_s || \
                    field_sel->u.l2_l3.mpls_label0_ttl || \
                    field_sel->u.l2_l3.mpls_label1_ttl || \
                    field_sel->u.l2_l3.mpls_label2_ttl;


    if((field_sel->u.l2_l3.l4_type || field_sel->u.l2_l3.l4_sub_type)||(DRV_FROM_TMM(lchip)&&is_capwap))
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " API or some feature is not supported \n");
        return CTC_E_NOT_SUPPORT;
    }

    if (field_sel->u.l2_l3.aware_tunnel_info_en)
    {
        if ((is_gre + is_nvgre + is_vxlan + is_capwap) > 1 )
        {
            return CTC_E_PARAM_CONFLICT;
        }
      if ((is_icmp + is_igmp + is_l4_port ) > 1 )
       {

           return CTC_E_PARAM_CONFLICT;
       }
    }
    else if(is_protocol)
    {
        if((is_gre + is_nvgre +is_vxlan) > 1)
        {
            return CTC_E_PARAM_CONFLICT;
        }
        if((is_gre || is_nvgre ||is_vxlan)&&(is_icmp||is_l4_port||is_igmp))
        {
             return CTC_E_PARAM_CONFLICT;
        }
    }
    else
    {
        if((is_gre + is_nvgre + is_icmp + is_igmp + is_vxlan + is_l4_port) > 1)
        {
             return CTC_E_PARAM_CONFLICT;
        }
    }

    if((!DRV_FROM_TMM(lchip))&&((field_sel->u.l2_l3.ip_sa && field_sel->u.l2_l3.src_cid) || (field_sel->u.l2_l3.ip_da && field_sel->u.l2_l3.src_cid)))
    {
        return CTC_E_PARAM_CONFLICT;
    }

    if((!DRV_FROM_TMM(lchip))&&((field_sel->u.l2_l3.ctag_cfi || field_sel->u.l2_l3.ctag_cos || field_sel->u.l2_l3.ctag_vlan) &&
        (field_sel->u.l2_l3.stag_cfi || field_sel->u.l2_l3.stag_cos || field_sel->u.l2_l3.stag_vlan)))
    {
        return CTC_E_PARAM_CONFLICT;
    }

    if(((!DRV_FROM_TMM(lchip))&&(is_mpls && (field_sel->u.l2_l3.ecn || field_sel->u.l2_l3.ttl || field_sel->u.l2_l3.dscp || \
                        field_sel->u.l2_l3.ip_sa || field_sel->u.l2_l3.ip_da || field_sel->u.l2_l3.aware_tunnel_info_en)))
            ||((DRV_FROM_TMM(lchip))&&(is_mpls && (field_sel->u.l2_l3.ecn || field_sel->u.l2_l3.ttl || field_sel->u.l2_l3.dscp || \
                        field_sel->u.l2_l3.ip_sa || field_sel->u.l2_l3.ip_da))) ) /* TMM mergeData not use union*/
    {
        return CTC_E_PARAM_CONFLICT;
    }

    if(!DRV_FROM_TMM(lchip) && (field_sel->u.l2_l3.aware_tunnel_info_en && (field_sel->u.l2_l3.ip_protocol || field_sel->u.l2_l3.ip_frag || \
                        field_sel->u.l2_l3.ip_identification || field_sel->u.l2_l3.vrfid || field_sel->u.l2_l3.tcp_flags)))
    {
        return CTC_E_PARAM_CONFLICT;
    }
    if(is_capwap && !field_sel->u.l2_l3.aware_tunnel_info_en)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "capwap info must use merge key\n");
        return CTC_E_NOT_SUPPORT;
    }

    sal_memset(&hash_field, 0, sizeof(IpfixL2L3HashFieldSelect_m));

    if (DRV_FROM_AT(lchip))
    {
        SetIpfixL2L3HashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);/*AT...*/
    }

    SetIpfixL2L3HashFieldSelect(V,  vlanIdEn_f       , &hash_field,field_sel->u.l2_l3.stag_vlan || field_sel->u.l2_l3.ctag_vlan);
    SetIpfixL2L3HashFieldSelect(V,  cfiEn_f       , &hash_field,field_sel->u.l2_l3.stag_cfi || field_sel->u.l2_l3.ctag_cfi);
    SetIpfixL2L3HashFieldSelect(V,  cosEn_f       , &hash_field,field_sel->u.l2_l3.stag_cos || field_sel->u.l2_l3.ctag_cos);
    if(field_sel->u.l2_l3.ctag_cfi || field_sel->u.l2_l3.ctag_cos || field_sel->u.l2_l3.ctag_vlan ||
        field_sel->u.l2_l3.stag_cfi || field_sel->u.l2_l3.stag_cos || field_sel->u.l2_l3.stag_vlan)
    {
        SetIpfixL2L3HashFieldSelect(V,  vlanIdValidEn_f  , &hash_field,1);
    }

    if(DRV_FROM_TMM(lchip))
    {
        SetIpfixL2L3HashFieldSelect(V,  svlanIdEn_f       , &hash_field,field_sel->u.l2_l3.stag_vlan);
        SetIpfixL2L3HashFieldSelect(V,  scfiEn_f       , &hash_field,field_sel->u.l2_l3.stag_cfi);
        SetIpfixL2L3HashFieldSelect(V,  scosEn_f       , &hash_field,field_sel->u.l2_l3.stag_cos);
        if(field_sel->u.l2_l3.stag_cfi || field_sel->u.l2_l3.stag_cos || field_sel->u.l2_l3.stag_vlan)
        {
            SetIpfixL2L3HashFieldSelect(V,  svlanIdValidEn_f  , &hash_field,1);
        }
        SetIpfixL2L3HashFieldSelect(V,  cvlanIdEn_f       , &hash_field,field_sel->u.l2_l3.ctag_vlan);
        SetIpfixL2L3HashFieldSelect(V,  ccfiEn_f       , &hash_field,field_sel->u.l2_l3.ctag_cfi);
        SetIpfixL2L3HashFieldSelect(V,  ccosEn_f       , &hash_field,field_sel->u.l2_l3.ctag_cos);
        if(field_sel->u.l2_l3.ctag_cfi || field_sel->u.l2_l3.ctag_cos || field_sel->u.l2_l3.ctag_vlan)
        {
            SetIpfixL2L3HashFieldSelect(V,  cvlanIdValidEn_f  , &hash_field,1);
        }
    }

    if (field_sel->u.l2_l3.ip_da)
    {
        IPFIX_IPV4_MASK_LEN_CHECK(field_sel->u.l2_l3.ip_da_mask);
        ip_prefix_len = field_sel->u.l2_l3.ip_da_mask - 1;

        SetIpfixL2L3HashFieldSelect(V,  ipDaPrefixLength_f, &hash_field, ip_prefix_len);
        SetIpfixL2L3HashFieldSelect(V,  ipDaEn_f, &hash_field, 1);
    }

    if (field_sel->u.l2_l3.ip_sa)
    {
        IPFIX_IPV4_MASK_LEN_CHECK(field_sel->u.l2_l3.ip_sa_mask);
        ip_prefix_len = field_sel->u.l2_l3.ip_sa_mask - 1;

       SetIpfixL2L3HashFieldSelect(V,  ipSaPrefixLength_f, &hash_field, ip_prefix_len);
       SetIpfixL2L3HashFieldSelect(V,  ipSaEn_f, &hash_field, 1);
    }
    SetIpfixL2L3HashFieldSelect(V, ipSaUseSrcCategoryId_f, &hash_field, field_sel->u.l2_l3.src_cid);
    SetIpfixL2L3HashFieldSelect(V, ipDaUseDstCategoryId_f, &hash_field, field_sel->u.l2_l3.dst_cid);
    SetIpfixL2L3HashFieldSelect(V, srcCategoryIdEn_f, &hash_field, field_sel->u.l2_l3.src_cid);
    SetIpfixL2L3HashFieldSelect(V, dstCategoryIdEn_f, &hash_field, field_sel->u.l2_l3.dst_cid);
    SetIpfixL2L3HashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.l2_l3.profile_id);
    SetIpfixL2L3HashFieldSelect(V,  dscpEn_f          , &hash_field,field_sel->u.l2_l3.dscp);
    SetIpfixL2L3HashFieldSelect(V,  ecnEn_f           , &hash_field,field_sel->u.l2_l3.ecn);
    SetIpfixL2L3HashFieldSelect(V,  ttlEn_f           , &hash_field,field_sel->u.l2_l3.ttl);
    SetIpfixL2L3HashFieldSelect(V,  etherTypeEn_f     , &hash_field,field_sel->u.l2_l3.eth_type);
    SetIpfixL2L3HashFieldSelect(V,  icmpOpcodeEn_f    , &hash_field,field_sel->u.l2_l3.icmp_code);
    SetIpfixL2L3HashFieldSelect(V,  icmpTypeEn_f      , &hash_field,field_sel->u.l2_l3.icmp_type);
    SetIpfixL2L3HashFieldSelect(V,  igmpTypeEn_f      , &hash_field,field_sel->u.l2_l3.igmp_type);

    SetIpfixL2L3HashFieldSelect(V,  l4DestPortEn_f, &hash_field,field_sel->u.l2_l3.l4_dst_port);
    SetIpfixL2L3HashFieldSelect(V,  l4SourcePortEn_f, &hash_field,field_sel->u.l2_l3.l4_src_port);
    SetIpfixL2L3HashFieldSelect(V,  labelNumEn_f, &hash_field,field_sel->u.l2_l3.label_num);
    SetIpfixL2L3HashFieldSelect(V,  macDaEn_f         , &hash_field,field_sel->u.l2_l3.mac_da);
    SetIpfixL2L3HashFieldSelect(V,  macSaEn_f         , &hash_field,field_sel->u.l2_l3.mac_sa);
    SetIpfixL2L3HashFieldSelect(V,  mplsExp0En_f      , &hash_field,field_sel->u.l2_l3.mpls_label0_exp);
    SetIpfixL2L3HashFieldSelect(V,  mplsExp1En_f      , &hash_field,field_sel->u.l2_l3.mpls_label1_exp);
    SetIpfixL2L3HashFieldSelect(V,  mplsExp2En_f      , &hash_field,field_sel->u.l2_l3.mpls_label2_exp);
    SetIpfixL2L3HashFieldSelect(V, mplsLabel0En_f    , &hash_field,field_sel->u.l2_l3.mpls_label0_label);
    SetIpfixL2L3HashFieldSelect(V, mplsLabel1En_f    , &hash_field,field_sel->u.l2_l3.mpls_label1_label);
    SetIpfixL2L3HashFieldSelect(V, mplsLabel2En_f    , &hash_field,field_sel->u.l2_l3.mpls_label2_label);
    SetIpfixL2L3HashFieldSelect(V, mplsSbit0En_f     , &hash_field,field_sel->u.l2_l3.mpls_label0_s);
    SetIpfixL2L3HashFieldSelect(V, mplsSbit1En_f     , &hash_field,field_sel->u.l2_l3.mpls_label1_s);
    SetIpfixL2L3HashFieldSelect(V, mplsSbit2En_f     , &hash_field,field_sel->u.l2_l3.mpls_label2_s);
    SetIpfixL2L3HashFieldSelect(V, mplsTtl0En_f      , &hash_field,field_sel->u.l2_l3.mpls_label0_ttl);
    SetIpfixL2L3HashFieldSelect(V, mplsTtl1En_f      , &hash_field,field_sel->u.l2_l3.mpls_label1_ttl);
    SetIpfixL2L3HashFieldSelect(V, mplsTtl2En_f      , &hash_field,field_sel->u.l2_l3.mpls_label2_ttl);

    SetIpfixL2L3HashFieldSelect(V, ignorVxlan_f    , &hash_field, !is_vxlan);
    SetIpfixL2L3HashFieldSelect(V, ignorGreWithKey_f    , &hash_field, !(is_gre+is_nvgre));
    SetIpfixL2L3HashFieldSelect(V, isVxlanEn_f    , &hash_field, (field_sel->u.l2_l3.aware_tunnel_info_en) ? 0 : is_vxlan);
    SetIpfixL2L3HashFieldSelect(V, ignorCapwap_f    , &hash_field, !is_capwap);

    SetIpfixL2L3HashFieldSelect(V, mergeKeyMode_f    , &hash_field,field_sel->u.l2_l3.aware_tunnel_info_en);
    SetIpfixL2L3HashFieldSelect(V, arpCodeEn_f    , &hash_field, field_sel->u.l2_l3.arp_code);/*AT..*/
    SetIpfixL2L3HashFieldSelect(V, arpMacSaEn_f    , &hash_field, field_sel->u.l2_l3.arp_mac_sa);/*AT..*/
    SetIpfixL2L3HashFieldSelect(V, arpMacDaEn_f    , &hash_field, field_sel->u.l2_l3.arp_mac_da);/*AT..*/

    if(field_sel->u.l2_l3.aware_tunnel_info_en)
    {
        SetIpfixL2L3HashFieldSelect(V,  g1_mergeKeyVxlanVniEn_f    , &hash_field,is_vxlan);
        SetIpfixL2L3HashFieldSelect(V,  g1_mergeKeyGreKeyEn_f      , &hash_field, is_gre);
        SetIpfixL2L3HashFieldSelect(V,  g1_mergeKeyNvgreVsidEn_f     , &hash_field, is_nvgre);
        SetIpfixL2L3HashFieldSelect(V, g1_mergeKeyCapwapRadioMacEn_f, &hash_field, field_sel->u.l2_l3.wlan_radio_mac);
        SetIpfixL2L3HashFieldSelect(V, g1_mergeKeyCapwapRidEn_f, &hash_field, field_sel->u.l2_l3.wlan_radio_id);
        SetIpfixL2L3HashFieldSelect(V, g1_mergeKeyCapwapControlPktEn_f, &hash_field, field_sel->u.l2_l3.wlan_ctl_packet);
    }

    SetIpfixL2L3HashFieldSelect(V,  vxlanVniEn_f    , &hash_field, is_vxlan);
    SetIpfixL2L3HashFieldSelect(V,  greKeyEn_f    , &hash_field, is_gre);
    SetIpfixL2L3HashFieldSelect(V,  nvgreVsidEn_f    , &hash_field, is_nvgre);

    SetIpfixL2L3HashFieldSelect(V,  g2_layer3HeaderProtocolEn_f  , &hash_field,field_sel->u.l2_l3.ip_protocol);
    if(!DRV_FROM_TMM(lchip))
    {
        SetIpfixL2L3HashFieldSelect(V,  g2_vrfIdEn_f  , &hash_field, !!field_sel->u.l2_l3.vrfid);
    }
    else
    {
        SetIpfixL2L3HashFieldSelect(V,  vrfIdEn_f  , &hash_field, !!field_sel->u.l2_l3.vrfid);
    }
    SetIpfixL2L3HashFieldSelect(V,  g2_ipIdentificationEn_f  , &hash_field, !!field_sel->u.l2_l3.ip_identification);
    SetIpfixL2L3HashFieldSelect(V,  g2_fragInfoEn_f  , &hash_field, !!field_sel->u.l2_l3.ip_frag);
    SetIpfixL2L3HashFieldSelect(V,  g2_tcpFlagsEn_f  , &hash_field, field_sel->u.l2_l3.tcp_flags);

    if(field_sel->u.l2_l3.gport)
    {
        global_port_type = 1;
    }
    else if(field_sel->u.l2_l3.logic_port)
    {
        global_port_type = 2;
    }
    else if(field_sel->u.l2_l3.metadata)
    {
        if (DRV_IS_DUET2(lchip))
        {
            global_port_type = 3;
        }
        else
        {
            global_port_type = 4;
        }
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixL2L3HashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);
    SetIpfixL2L3HashFieldSelect(V, vsiIdEn_f, &hash_field, field_sel->u.l2_l3.fid); /*TMM...*/
    SetIpfixL2L3HashFieldSelect(V, tcpBidiFlowSessionEn_f, &hash_field, field_sel->u.l2_l3.sym_session_en); /*TMM...*/

    cmd = DRV_IOW( IpfixL2L3HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL2L3HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixL2L3HashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_set_hash_field_sel_chk(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    uint8 v4_full_key_except_short = (field_sel->u.ipv4.gport && (!DRV_FROM_AT(lchip))) || \
                field_sel->u.ipv4.logic_port|| \
                field_sel->u.ipv4.metadata|| \
                field_sel->u.ipv4.dscp || \
                field_sel->u.ipv4.ttl || \
                field_sel->u.ipv4.ecn || \
                field_sel->u.ipv4.ip_identification|| \
                field_sel->u.ipv4.ip_pkt_len|| \
                field_sel->u.ipv4.ip_frag || \
                field_sel->u.ipv4.tcp_flags || \
                (field_sel->u.ipv4.vrfid && (!DRV_FROM_AT(lchip)))|| \
                (field_sel->u.ipv4.fid && (!DRV_FROM_AT(lchip)))|| \
                field_sel->u.ipv4.vxlan_vni|| \
                field_sel->u.ipv4.gre_key || \
                field_sel->u.ipv4.nvgre_key || \
                field_sel->u.ipv4.src_cid || \
                field_sel->u.ipv4.dst_cid;
    uint8 v6_full_key_except_short = field_sel->u.ipv6.gport || \
                field_sel->u.ipv6.logic_port || \
                field_sel->u.ipv6.metadata || \
                field_sel->u.ipv6.dscp || \
                field_sel->u.ipv6.ttl || \
                field_sel->u.ipv6.ecn || \
                field_sel->u.ipv6.flow_label || \
                field_sel->u.ipv6.l4_type|| \
                field_sel->u.ipv6.l4_sub_type|| \
                (field_sel->u.ipv6.fid && (!DRV_FROM_AT(lchip)))|| \
                field_sel->u.ipv6.vxlan_vni|| \
                field_sel->u.ipv6.gre_key || \
                field_sel->u.ipv6.nvgre_key || \
                field_sel->u.ipv6.aware_tunnel_info_en|| \
                field_sel->u.ipv6.wlan_radio_mac|| \
                field_sel->u.ipv6.wlan_radio_id ||  \
                field_sel->u.ipv6.wlan_ctl_packet|| \
                field_sel->u.ipv6.ip_frag || \
                field_sel->u.ipv6.tcp_flags || \
                field_sel->u.ipv6.src_cid || \
                field_sel->u.ipv6.dst_cid;
    uint8 mpls_full_key_except_short = field_sel->u.mpls.gport || \
                field_sel->u.mpls.logic_port|| \
                field_sel->u.mpls.metadata|| \
                field_sel->u.mpls.fid;
    uint8 udf_full_key_except_short = field_sel->u.udf.gport || \
                field_sel->u.udf.logic_port|| \
                field_sel->u.udf.metadata;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_MAX_VALUE_CHECK(field_sel->field_sel_id, MCHIP_CAP(SYS_CAP_IPFIX_MAX_HASH_SEL_ID));
    if((CTC_IPFIX_KEY_HASH_UDF == field_sel->key_type)&&(field_sel->field_sel_id>0)&&(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        return CTC_E_INVALID_PARAM;
    }

    if(p_usw_ipfix_master[lchip]->short_mode)
    {
        switch(field_sel->key_type)
        {
        case CTC_IPFIX_KEY_HASH_IPV4:
             if(v4_full_key_except_short )
             {
                return CTC_E_NOT_SUPPORT;
             }
             break;
        case CTC_IPFIX_KEY_HASH_IPV6:
             if(v6_full_key_except_short)
             {
                return CTC_E_NOT_SUPPORT;
             }
             break;
        case CTC_IPFIX_KEY_HASH_MPLS:
             if(mpls_full_key_except_short)
            {
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_IPFIX_KEY_HASH_UDF:
             if(udf_full_key_except_short)
             {
                return CTC_E_NOT_SUPPORT;
             }
            break;
        default:                                    /* mac_key, L2L3key no short key */
            return CTC_E_NOT_SUPPORT;
            break;
        }
    }

    switch (field_sel->key_type)
    {
    case CTC_IPFIX_KEY_HASH_IPV4_SINGLE:
        if (v4_full_key_except_short )
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_IPFIX_KEY_HASH_IPV6_SINGLE:
        if (v6_full_key_except_short)
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_IPFIX_KEY_HASH_MPLS_SINGLE:
        if (mpls_full_key_except_short)
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_IPFIX_KEY_HASH_UDF_SINGLE:
        if (udf_full_key_except_short)
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    default :
        break;
    }

    return CTC_E_NONE;
}

extern int32
sys_usw_ipfix_set_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    int32 ret = CTC_E_NONE;
    SYS_IPFIX_INIT_CHECK(lchip);

    CTC_PTR_VALID_CHECK(field_sel);

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_ERROR_RETURN(_sys_usw_ipfix_set_hash_field_sel_chk(lchip, field_sel));

    SYS_IPFIX_LOCK(lchip);
    if (p_usw_ipfix_master[lchip]->callbacks_set_hashsel[field_sel->key_type])
    {
        CTC_ERROR_GOTO(p_usw_ipfix_master[lchip]->callbacks_set_hashsel[field_sel->key_type](lchip, field_sel), ret, error_pro);
    }
    else
    {
        ret = CTC_E_NOT_SUPPORT;
    }
    error_pro:
        SYS_IPFIX_UNLOCK(lchip);
        return ret;
}



int32
_sys_usw_ipfix_get_mac_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL2HashFieldSelect_m l2_hash_field;
    uint32 cmd = 0;

    cmd = DRV_IOR((DRV_FROM_AT(lchip))?IpfixL2HashFieldSelect0_t:IpfixL2HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &l2_hash_field));
    field_sel->u.mac.profile_id = GetIpfixL2HashFieldSelect(V, ipfixCfgProfileIdEn_f, &l2_hash_field);
    if (DRV_FROM_TMM(lchip))
    {
        field_sel->u.mac.ctag_cfi = GetIpfixL2HashFieldSelect(V, ccfiEn_f, &l2_hash_field);
        field_sel->u.mac.ctag_cos = GetIpfixL2HashFieldSelect(V, ccosEn_f, &l2_hash_field);
        field_sel->u.mac.ctag_vlan = GetIpfixL2HashFieldSelect(V, cvlanIdEn_f, &l2_hash_field);
        field_sel->u.mac.cfi = GetIpfixL2HashFieldSelect(V, scfiEn_f, &l2_hash_field);
        field_sel->u.mac.cos = GetIpfixL2HashFieldSelect(V, scosEn_f, &l2_hash_field);
        field_sel->u.mac.vlan_id = GetIpfixL2HashFieldSelect(V, svlanIdEn_f, &l2_hash_field);
        field_sel->u.mac.fid = GetIpfixL2HashFieldSelect(V, vsiIdEn_f, &l2_hash_field);
    }
    else
    {
        field_sel->u.mac.cfi = GetIpfixL2HashFieldSelect(V, cfiEn_f, &l2_hash_field);
        field_sel->u.mac.cos = GetIpfixL2HashFieldSelect(V, cosEn_f, &l2_hash_field);
        field_sel->u.mac.vlan_id = GetIpfixL2HashFieldSelect(V, vlanIdEn_f, &l2_hash_field);
    }

    field_sel->u.mac.eth_type = GetIpfixL2HashFieldSelect(V, etherTypeEn_f, &l2_hash_field);
    field_sel->u.mac.mac_da = GetIpfixL2HashFieldSelect(V, macDaEn_f, &l2_hash_field);
    field_sel->u.mac.mac_sa = GetIpfixL2HashFieldSelect(V, macSaEn_f, &l2_hash_field);
    field_sel->u.mac.src_cid = GetIpfixL2HashFieldSelect(V, srcCategoryIdEn_f, &l2_hash_field);
    field_sel->u.mac.dst_cid = GetIpfixL2HashFieldSelect(V, dstCategoryIdEn_f, &l2_hash_field);
     /*field_sel->u.mac.ctag_valid = GetIpfixL2HashFieldSelect(V, flowL2KeyUseCvlanEn_f, &l2_hash_field);*/
    switch(GetIpfixL2HashFieldSelect(V, globalPortType_f, &l2_hash_field))
    {
        case 1:
            field_sel->u.mac.gport = 1;
            break;
        case 2:
            field_sel->u.mac.logic_port = 1;
            break;
        case 3:
        case 4:
            field_sel->u.mac.metadata = 1;
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}


int32
_sys_usw_ipfix_get_v4_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL3Ipv4HashFieldSelect_m v4_hash_field;
    IpfixShortIpv4HashFieldSelect_m v4_short_hash_field;
    uint32 cmd = 0;

    cmd = DRV_IOR((DRV_FROM_AT(lchip))?IpfixL3Ipv4HashFieldSelect0_t:IpfixL3Ipv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &v4_hash_field));
    cmd = DRV_IOR(IpfixShortIpv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &v4_short_hash_field));
    field_sel->u.ipv4.profile_id = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, ipfixCfgProfileIdEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V, ipfixCfgProfileIdEn_f, &v4_hash_field);
    field_sel->u.ipv4.ip_da = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V,  ipDaEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V,  ipDaEn_f, &v4_hash_field);
    field_sel->u.ipv4.ip_da_mask = p_usw_ipfix_master[lchip]->short_mode ? \
       (field_sel->u.ipv4.ip_da ? (GetIpfixShortIpv4HashFieldSelect(V,  ipDaPrefixLength_f, &v4_short_hash_field) + 1) : 0): \
       ( field_sel->u.ipv4.ip_da ? (GetIpfixL3Ipv4HashFieldSelect(V,  ipDaPrefixLength_f, &v4_hash_field) + 1) : 0);
    field_sel->u.ipv4.ip_sa =p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V,  ipSaEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V,  ipSaEn_f, &v4_hash_field);
    field_sel->u.ipv4.ip_sa_mask = p_usw_ipfix_master[lchip]->short_mode ? \
        (field_sel->u.ipv4.ip_sa ? (GetIpfixShortIpv4HashFieldSelect(V,  ipSaPrefixLength_f, &v4_short_hash_field)  + 1) : 0): \
        (field_sel->u.ipv4.ip_sa ? (GetIpfixL3Ipv4HashFieldSelect(V,  ipSaPrefixLength_f, &v4_hash_field)  + 1) : 0);
    field_sel->u.ipv4.ip_protocol = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, layer3HeaderProtocolEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V, layer3HeaderProtocolEn_f, &v4_hash_field);
    field_sel->u.ipv4.l4_dst_port = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, l4DestPortEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V, l4DestPortEn_f, &v4_hash_field);
    field_sel->u.ipv4.l4_src_port = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, l4SourcePortEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V, l4SourcePortEn_f, &v4_hash_field);
    field_sel->u.ipv4.icmp_code = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, icmpOpcodeEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V, icmpOpcodeEn_f, &v4_hash_field);
    field_sel->u.ipv4.icmp_type = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, icmpTypeEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V, icmpTypeEn_f, &v4_hash_field);
    field_sel->u.ipv4.igmp_type = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, igmpTypeEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V, igmpTypeEn_f, &v4_hash_field);
    field_sel->u.ipv4.sym_session_en= p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, tcpBidiFlowSessionEn_f, &v4_short_hash_field) : GetIpfixL3Ipv4HashFieldSelect(V, tcpBidiFlowSessionEn_f, &v4_hash_field);

    field_sel->u.ipv4.dscp = GetIpfixL3Ipv4HashFieldSelect(V, dscpEn_f, &v4_hash_field);
    field_sel->u.ipv4.gre_key = GetIpfixL3Ipv4HashFieldSelect(V, greKeyEn_f, &v4_hash_field);
    field_sel->u.ipv4.nvgre_key = GetIpfixL3Ipv4HashFieldSelect(V, nvgreVsidEn_f, &v4_hash_field);

    field_sel->u.ipv4.vxlan_vni = GetIpfixL3Ipv4HashFieldSelect(V, vxlanVniEn_f, &v4_hash_field);
    field_sel->u.ipv4.ttl= GetIpfixL3Ipv4HashFieldSelect(V, ttlEn_f, &v4_hash_field);
    field_sel->u.ipv4.ecn= GetIpfixL3Ipv4HashFieldSelect(V, ecnEn_f, &v4_hash_field);

    field_sel->u.ipv4.src_cid = GetIpfixL3Ipv4HashFieldSelect(V, srcCategoryIdEn_f, &v4_hash_field);
    field_sel->u.ipv4.dst_cid = GetIpfixL3Ipv4HashFieldSelect(V, dstCategoryIdEn_f, &v4_hash_field);
    field_sel->u.ipv4.fid = GetIpfixL3Ipv4HashFieldSelect(V, vsiIdEn_f, &v4_hash_field);/*TMM...*/
    if (!DRV_FROM_TMM(lchip))
    {
        switch (GetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &v4_hash_field))
        {
            case 0:
                field_sel->u.ipv4.ip_frag = GetIpfixL3Ipv4HashFieldSelect(V, u1_g1_fragInfoEn_f, &v4_hash_field);
                field_sel->u.ipv4.tcp_flags = GetIpfixL3Ipv4HashFieldSelect(V, u1_g1_tcpFlagsEn_f, &v4_hash_field);
                break;
            case 1:
                field_sel->u.ipv4.ip_identification = GetIpfixL3Ipv4HashFieldSelect(V, u1_g2_ipIdentificationEn_f, &v4_hash_field);
                break;
            case 2:
                field_sel->u.ipv4.ip_frag = GetIpfixL3Ipv4HashFieldSelect(V, u1_g3_fragInfoEn_f, &v4_hash_field);
                field_sel->u.ipv4.ip_pkt_len = GetIpfixL3Ipv4HashFieldSelect(V, u1_g3_ipLengthEn_f, &v4_hash_field);
                break;
            default:
                field_sel->u.ipv4.ip_frag = GetIpfixL3Ipv4HashFieldSelect(V, u1_g4_fragInfoEn_f, &v4_hash_field);
                field_sel->u.ipv4.vrfid = GetIpfixL3Ipv4HashFieldSelect(V, u1_g4_vrfIdEn_f, &v4_hash_field);
                break;
        }
    }
    else
    {
        switch (GetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &v4_hash_field))
        {
            case 0:
                field_sel->u.ipv4.vrfid = GetIpfixL3Ipv4HashFieldSelect(V, vrfIdEn_f, &v4_hash_field);
                break;
            case 1:
                field_sel->u.ipv4.ip_identification = GetIpfixL3Ipv4HashFieldSelect(V, ipIdentificationEn_f, &v4_hash_field);
                break;
            case 2:
                field_sel->u.ipv4.ip_pkt_len = GetIpfixL3Ipv4HashFieldSelect(V, ipLengthEn_f, &v4_hash_field);
                break;
        }
    }

    switch(GetIpfixL3Ipv4HashFieldSelect(V, globalPortType_f, &v4_hash_field))
    {
        case 1:
            field_sel->u.ipv4.gport = 1;
            break;
        case 2:
            field_sel->u.ipv4.logic_port = 1;
            break;
        case 3:
        case 4:
            field_sel->u.ipv4.metadata = 1;
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_get_mpls_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL3MplsHashFieldSelect_m mpls_hash_field;
    IpfixShortIpv4HashFieldSelect_m v4_short_hash_field;
    uint32 cmd = 0;

    cmd = DRV_IOR((DRV_FROM_AT(lchip))?IpfixL3MplsHashFieldSelect0_t:IpfixL3MplsHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &mpls_hash_field));
    cmd = DRV_IOR(IpfixShortIpv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &v4_short_hash_field));
    field_sel->u.mpls.profile_id = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, ipfixCfgProfileIdEn_f, &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, ipfixCfgProfileIdEn_f, &mpls_hash_field);
    field_sel->u.mpls.label_num = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V,  labelNumEn_f, &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V,  labelNumEn_f, &mpls_hash_field);
    field_sel->u.mpls.mpls_label0_exp = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V,  mplsExp0En_f, &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V,  mplsExp0En_f, &mpls_hash_field);
    field_sel->u.mpls.mpls_label1_exp = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V,  mplsExp1En_f, &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V,  mplsExp1En_f      ,&mpls_hash_field);
    field_sel->u.mpls.mpls_label2_exp = p_usw_ipfix_master[lchip]->short_mode ? \
       GetIpfixShortIpv4HashFieldSelect(V,  mplsExp2En_f, &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V,  mplsExp2En_f      ,&mpls_hash_field);
    field_sel->u.mpls.mpls_label0_label = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, mplsLabel0En_f    , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsLabel0En_f    , &mpls_hash_field);
    field_sel->u.mpls.mpls_label1_label = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, mplsLabel1En_f    , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsLabel1En_f    , &mpls_hash_field);
    field_sel->u.mpls.mpls_label2_label = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, mplsLabel2En_f    , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsLabel2En_f    , &mpls_hash_field);
    field_sel->u.mpls.mpls_label0_s = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, mplsSbit0En_f     , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsSbit0En_f     , &mpls_hash_field);
    field_sel->u.mpls.mpls_label1_s = p_usw_ipfix_master[lchip]->short_mode ? \
       GetIpfixShortIpv4HashFieldSelect(V, mplsSbit1En_f     , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsSbit1En_f     , &mpls_hash_field);
    field_sel->u.mpls.mpls_label2_s = p_usw_ipfix_master[lchip]->short_mode ? \
       GetIpfixShortIpv4HashFieldSelect(V, mplsSbit2En_f     , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsSbit2En_f     , &mpls_hash_field);
    field_sel->u.mpls.mpls_label0_ttl = p_usw_ipfix_master[lchip]->short_mode ? \
         GetIpfixShortIpv4HashFieldSelect(V, mplsTtl0En_f      , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsTtl0En_f      , &mpls_hash_field);
    field_sel->u.mpls.mpls_label1_ttl = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv4HashFieldSelect(V, mplsTtl1En_f      , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsTtl1En_f      , &mpls_hash_field);
    field_sel->u.mpls.mpls_label2_ttl = p_usw_ipfix_master[lchip]->short_mode ? \
       GetIpfixShortIpv4HashFieldSelect(V, mplsTtl2En_f      , &v4_short_hash_field) : GetIpfixL3MplsHashFieldSelect(V, mplsTtl2En_f      , &mpls_hash_field);
    if (!p_usw_ipfix_master[lchip]->short_mode)
    {
        field_sel->u.mpls.fid = GetIpfixL3MplsHashFieldSelect(V, vsiIdEn_f      , &mpls_hash_field);/*TMM...*/
    }
    switch(GetIpfixL3MplsHashFieldSelect(V, globalPortType_f, &mpls_hash_field))
    {
        case 1:
            field_sel->u.mpls.gport = 1;
            break;
        case 2:
            field_sel->u.mpls.logic_port = 1;
            break;
        case 3:
        case 4:
            field_sel->u.mpls.metadata = 1;
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_get_udf_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
  
    uint32 cmd = 0;
    uint32     hw_udf[8] = {0};
    IpfixUdfHashFieldSelect_m udf_hash_field;
    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(field_sel);
    CTC_MAX_VALUE_CHECK(field_sel_id, MCHIP_CAP(SYS_CAP_IPFIX_MAX_HASH_SEL_ID));

    cmd = DRV_IOR(IpfixUdfHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, cmd, &udf_hash_field));
    field_sel->u.udf.profile_id = GetIpfixUdfHashFieldSelect(V, ipfixCfgProfileIdEn_f, &udf_hash_field);
    field_sel->u.udf.udf_valid = GetIpfixUdfHashFieldSelect(V, udfValidEn_f, &udf_hash_field);
    GetIpfixUdfHashFieldSelect(A, udfDataEn_f, &udf_hash_field, hw_udf);
    SYS_USW_SET_USR_UDF(lchip,  field_sel->u.udf.udf_data, hw_udf);
            //field_sel->u.udf.udf_id;
    switch(GetIpfixUdfHashFieldSelect(V, globalPortType_f, &udf_hash_field))
    {
        case 1:
            field_sel->u.udf.gport = 1;
            break;
        case 2:
            field_sel->u.udf.logic_port = 1;
            break;
        case 3:
        case 4:
            field_sel->u.udf.metadata = 1;
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_get_v6_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL3Ipv6HashFieldSelect_m  v6_hash_field;
    IpfixShortIpv6HashFieldSelect_m v6_short_hash_field;
    uint32 cmd = 0;

    cmd = DRV_IOR((DRV_FROM_AT(lchip))?IpfixL3Ipv6HashFieldSelect0_t:IpfixL3Ipv6HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &v6_hash_field));
    cmd = DRV_IOR(IpfixShortIpv6HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &v6_short_hash_field));
    field_sel->u.ipv6.ip_da = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V,  ipDaEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, ipDaEn_f, &v6_hash_field);
    field_sel->u.ipv6.ip_da_mask = p_usw_ipfix_master[lchip]->short_mode ? \
        (field_sel->u.ipv6.ip_da ? ((GetIpfixShortIpv6HashFieldSelect(V, ipDaPrefixLength_f, &v6_short_hash_field)+1)<<2) : 0) : \
        (field_sel->u.ipv6.ip_da ? ((GetIpfixL3Ipv6HashFieldSelect(V, ipDaPrefixLength_f, &v6_hash_field)+1)<<2) : 0);
    field_sel->u.ipv6.ip_sa = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V,  ipSaEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, ipSaEn_f, &v6_hash_field);
    field_sel->u.ipv6.ip_sa_mask = p_usw_ipfix_master[lchip]->short_mode ? \
        (field_sel->u.ipv6.ip_sa ? ((GetIpfixShortIpv6HashFieldSelect(V, ipSaPrefixLength_f, &v6_short_hash_field)+1)<<2) : 0) : \
        (field_sel->u.ipv6.ip_sa ? ((GetIpfixL3Ipv6HashFieldSelect(V, ipSaPrefixLength_f, &v6_hash_field)+1)<<2) : 0);
    field_sel->u.ipv6.ip_protocol = p_usw_ipfix_master[lchip]->short_mode ? \
       GetIpfixShortIpv6HashFieldSelect(V, layer3HeaderProtocolEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, layer3HeaderProtocolEn_f, &v6_hash_field);
    field_sel->u.ipv6.l4_dst_port = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V, l4DestPortEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, l4DestPortEn_f, &v6_hash_field);
    field_sel->u.ipv6.l4_src_port = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V, l4SourcePortEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, l4SourcePortEn_f, &v6_hash_field);
    field_sel->u.ipv6.icmp_code = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V, icmpOpcodeEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, icmpOpcodeEn_f, &v6_hash_field);
    field_sel->u.ipv6.icmp_type = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V, icmpTypeEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, icmpTypeEn_f, &v6_hash_field);
    field_sel->u.ipv6.igmp_type = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V, igmpTypeEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, igmpTypeEn_f, &v6_hash_field);

    field_sel->u.ipv6.sym_session_en= p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V, tcpBidiFlowSessionEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, tcpBidiFlowSessionEn_f, &v6_hash_field);
    field_sel->u.ipv6.profile_id = p_usw_ipfix_master[lchip]->short_mode ? \
        GetIpfixShortIpv6HashFieldSelect(V, ipfixCfgProfileIdEn_f, &v6_short_hash_field) : GetIpfixL3Ipv6HashFieldSelect(V, ipfixCfgProfileIdEn_f, &v6_hash_field);


    field_sel->u.ipv6.dscp = GetIpfixL3Ipv6HashFieldSelect(V, dscpEn_f, &v6_hash_field);
    field_sel->u.ipv6.gre_key = GetIpfixL3Ipv6HashFieldSelect(V, greKeyEn_f, &v6_hash_field) ||
                                    GetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyGreKeyEn_f, &v6_hash_field);
    field_sel->u.ipv6.nvgre_key = GetIpfixL3Ipv6HashFieldSelect(V, nvgreVsidEn_f, &v6_hash_field) ||
                                    GetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyNvgreVsidEn_f, &v6_hash_field);
    field_sel->u.ipv6.aware_tunnel_info_en = GetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyMode_f, &v6_hash_field);

    field_sel->u.ipv6.flow_label = GetIpfixL3Ipv6HashFieldSelect(V, g1_ipv6FlowLabelEn_f, &v6_hash_field);
    field_sel->u.ipv6.vxlan_vni = GetIpfixL3Ipv6HashFieldSelect(V, vxlanVniEn_f, &v6_hash_field) ||
                                    GetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyVxlanVniEn_f, &v6_hash_field);
    field_sel->u.ipv6.wlan_radio_mac = GetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyCapwapRadioMacEn_f, &v6_hash_field);
    field_sel->u.ipv6.wlan_radio_id = GetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyCapwapRidEn_f, &v6_hash_field);
    field_sel->u.ipv6.wlan_ctl_packet = GetIpfixL3Ipv6HashFieldSelect(V, g1_mergeKeyCapwapControlPktEn_f, &v6_hash_field);
    field_sel->u.ipv6.ttl = GetIpfixL3Ipv6HashFieldSelect(V, g1_ttlEn_f, &v6_hash_field);
    field_sel->u.ipv6.ecn = GetIpfixL3Ipv6HashFieldSelect(V, g1_ecnEn_f, &v6_hash_field);
    field_sel->u.ipv6.ip_frag = GetIpfixL3Ipv6HashFieldSelect(V, g1_fragInfoEn_f, &v6_hash_field);
    field_sel->u.ipv6.tcp_flags = GetIpfixL3Ipv6HashFieldSelect(V, g1_tcpFlagsEn_f, &v6_hash_field);
    field_sel->u.ipv6.src_cid = GetIpfixL3Ipv6HashFieldSelect(V, g1_srcCategoryIdEn_f, &v6_hash_field);
    field_sel->u.ipv6.dst_cid = GetIpfixL3Ipv6HashFieldSelect(V, g1_dstCategoryIdEn_f, &v6_hash_field);
    field_sel->u.ipv6.fid = GetIpfixL3Ipv6HashFieldSelect(V, vsiIdEn_f, &v6_hash_field);/*TMM...*/
    field_sel->u.ipv6.vrfid = GetIpfixL3Ipv6HashFieldSelect(V, vrfIdEn_f, &v6_hash_field);/*AT...*/

    switch(GetIpfixL3Ipv6HashFieldSelect(V, globalPortType_f, &v6_hash_field))
    {
        case 1:
            field_sel->u.ipv6.gport = 1;
            break;
        case 2:
            field_sel->u.ipv6.logic_port = 1;
            break;
        case 3:
        case 4:
            field_sel->u.ipv6.metadata = 1;
            break;
        default:
            break;
    }
    if (DRV_FROM_AT(lchip))
    {
        field_sel->u.ipv6.fid = GetIpfixL3Ipv6HashFieldSelect(V, vsiIdEn_f, &v6_hash_field);
        field_sel->u.ipv6.vrfid = GetIpfixL3Ipv6HashFieldSelect(V, vrfIdEn_f, &v6_hash_field);
    }

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_get_l2l3_hash_sel(uint8 lchip,uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixL2L3HashFieldSelect_m  l2l3_hash_field;
    uint32 cmd = 0;

    cmd = DRV_IOR((DRV_FROM_AT(lchip))?IpfixL2L3HashFieldSelect0_t:IpfixL2L3HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &l2l3_hash_field));

    field_sel->u.l2_l3.stag_cfi= GetIpfixL2L3HashFieldSelect(V, cfiEn_f       , &l2l3_hash_field);
    field_sel->u.l2_l3.stag_cos= GetIpfixL2L3HashFieldSelect(V, cosEn_f       , &l2l3_hash_field);
    field_sel->u.l2_l3.stag_vlan= GetIpfixL2L3HashFieldSelect(V, vlanIdEn_f       , &l2l3_hash_field);
    field_sel->u.l2_l3.src_cid = GetIpfixL2L3HashFieldSelect(V, srcCategoryIdEn_f, &l2l3_hash_field);
    field_sel->u.l2_l3.dst_cid = GetIpfixL2L3HashFieldSelect(V, dstCategoryIdEn_f, &l2l3_hash_field);
    field_sel->u.l2_l3.profile_id = GetIpfixL2L3HashFieldSelect(V, ipfixCfgProfileIdEn_f, &l2l3_hash_field);
    field_sel->u.l2_l3.dscp= GetIpfixL2L3HashFieldSelect(V,  dscpEn_f          , &l2l3_hash_field);
    field_sel->u.l2_l3.ecn= GetIpfixL2L3HashFieldSelect(V,  ecnEn_f           , &l2l3_hash_field);
    field_sel->u.l2_l3.eth_type = GetIpfixL2L3HashFieldSelect(V,  etherTypeEn_f     , &l2l3_hash_field);
    field_sel->u.l2_l3.icmp_code= GetIpfixL2L3HashFieldSelect(V,  icmpOpcodeEn_f    , &l2l3_hash_field);
    field_sel->u.l2_l3.icmp_type= GetIpfixL2L3HashFieldSelect(V,  icmpTypeEn_f      , &l2l3_hash_field);
    field_sel->u.l2_l3.igmp_type= GetIpfixL2L3HashFieldSelect(V,  igmpTypeEn_f      , &l2l3_hash_field);
    field_sel->u.l2_l3.ip_da = GetIpfixL2L3HashFieldSelect(V,  ipDaEn_f, &l2l3_hash_field);
    field_sel->u.l2_l3.ip_da_mask = field_sel->u.l2_l3.ip_da ? (GetIpfixL2L3HashFieldSelect(V,  ipDaPrefixLength_f, &l2l3_hash_field)+1) : 0;
    field_sel->u.l2_l3.ip_sa = GetIpfixL2L3HashFieldSelect(V,  ipSaEn_f, &l2l3_hash_field);
    field_sel->u.l2_l3.ip_sa_mask = field_sel->u.l2_l3.ip_sa ? (GetIpfixL2L3HashFieldSelect(V,  ipSaPrefixLength_f, &l2l3_hash_field)+1) : 0;
    field_sel->u.l2_l3.l4_dst_port = GetIpfixL2L3HashFieldSelect(V,  l4DestPortEn_f, &l2l3_hash_field);
    field_sel->u.l2_l3.l4_src_port= GetIpfixL2L3HashFieldSelect(V,  l4SourcePortEn_f, &l2l3_hash_field);
    field_sel->u.l2_l3.label_num= GetIpfixL2L3HashFieldSelect(V,  labelNumEn_f, &l2l3_hash_field);
    field_sel->u.l2_l3.mac_da= GetIpfixL2L3HashFieldSelect(V,  macDaEn_f         , &l2l3_hash_field);
    field_sel->u.l2_l3.mac_sa= GetIpfixL2L3HashFieldSelect(V,  macSaEn_f         , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label0_exp= GetIpfixL2L3HashFieldSelect(V,  mplsExp0En_f      , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label1_exp= GetIpfixL2L3HashFieldSelect(V,  mplsExp1En_f      , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label2_exp= GetIpfixL2L3HashFieldSelect(V,  mplsExp2En_f      , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label0_label= GetIpfixL2L3HashFieldSelect(V, mplsLabel0En_f    , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label1_label= GetIpfixL2L3HashFieldSelect(V, mplsLabel1En_f    , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label2_label= GetIpfixL2L3HashFieldSelect(V, mplsLabel2En_f    , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label0_s= GetIpfixL2L3HashFieldSelect(V, mplsSbit0En_f     , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label1_s= GetIpfixL2L3HashFieldSelect(V, mplsSbit1En_f     , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label2_s= GetIpfixL2L3HashFieldSelect(V, mplsSbit2En_f     , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label0_ttl = GetIpfixL2L3HashFieldSelect(V, mplsTtl0En_f      , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label1_ttl= GetIpfixL2L3HashFieldSelect(V, mplsTtl1En_f      , &l2l3_hash_field);
    field_sel->u.l2_l3.mpls_label2_ttl= GetIpfixL2L3HashFieldSelect(V, mplsTtl2En_f      , &l2l3_hash_field);
    field_sel->u.l2_l3.ttl= GetIpfixL2L3HashFieldSelect(V, ttlEn_f           , &l2l3_hash_field);
    field_sel->u.l2_l3.arp_code= GetIpfixL2L3HashFieldSelect(V, arpCodeEn_f      , &l2l3_hash_field);/*AT..*/
    field_sel->u.l2_l3.arp_mac_da= GetIpfixL2L3HashFieldSelect(V, arpMacDaEn_f      , &l2l3_hash_field);/*AT..*/
    field_sel->u.l2_l3.arp_mac_sa= GetIpfixL2L3HashFieldSelect(V, arpMacSaEn_f           , &l2l3_hash_field);/*AT..*/
    field_sel->u.l2_l3.aware_tunnel_info_en = GetIpfixL2L3HashFieldSelect(V, mergeKeyMode_f, &l2l3_hash_field);
    if(field_sel->u.l2_l3.aware_tunnel_info_en)
    {
        field_sel->u.l2_l3.vxlan_vni= GetIpfixL2L3HashFieldSelect(V,g1_mergeKeyVxlanVniEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.gre_key = GetIpfixL2L3HashFieldSelect(V,g1_mergeKeyGreKeyEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.nvgre_key = GetIpfixL2L3HashFieldSelect(V,g1_mergeKeyNvgreVsidEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.wlan_radio_mac = GetIpfixL2L3HashFieldSelect(V,g1_mergeKeyCapwapRadioMacEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.wlan_radio_id = GetIpfixL2L3HashFieldSelect(V,g1_mergeKeyCapwapRidEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.wlan_ctl_packet = GetIpfixL2L3HashFieldSelect(V,g1_mergeKeyCapwapControlPktEn_f, &l2l3_hash_field);
    }
    else
    {
        field_sel->u.l2_l3.vxlan_vni= GetIpfixL2L3HashFieldSelect(V,vxlanVniEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.gre_key = GetIpfixL2L3HashFieldSelect(V,greKeyEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.nvgre_key = GetIpfixL2L3HashFieldSelect(V,nvgreVsidEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.ip_protocol = GetIpfixL2L3HashFieldSelect(V,g2_layer3HeaderProtocolEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.vrfid = DRV_FROM_TMM(lchip) ? GetIpfixL2L3HashFieldSelect(V, vrfIdEn_f, &l2l3_hash_field):\
            GetIpfixL2L3HashFieldSelect(V,g2_vrfIdEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.ip_identification = GetIpfixL2L3HashFieldSelect(V,g2_ipIdentificationEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.ip_frag = GetIpfixL2L3HashFieldSelect(V,g2_fragInfoEn_f, &l2l3_hash_field);
        field_sel->u.l2_l3.tcp_flags = GetIpfixL2L3HashFieldSelect(V,g2_tcpFlagsEn_f, &l2l3_hash_field);
    }

    field_sel->u.l2_l3.fid = GetIpfixL2L3HashFieldSelect(V, vsiIdEn_f, &l2l3_hash_field); /*TMM...*/
    field_sel->u.l2_l3.sym_session_en = GetIpfixL2L3HashFieldSelect(V, tcpBidiFlowSessionEn_f, &l2l3_hash_field); /*TMM...*/

    switch(GetIpfixL2L3HashFieldSelect(V, globalPortType_f, &l2l3_hash_field))
    {
        case 1:
            field_sel->u.l2_l3.gport = 1;
            break;
        case 2:
            field_sel->u.l2_l3.logic_port = 1;
            break;
        case 3:
        case 4:
            field_sel->u.l2_l3.metadata = 1;
            break;
        default:
            break;
    }
    if (DRV_FROM_TMM(lchip))
    {
        field_sel->u.l2_l3.stag_vlan = GetIpfixL2L3HashFieldSelect(V,  svlanIdEn_f       , &l2l3_hash_field);
        field_sel->u.l2_l3.stag_cfi = GetIpfixL2L3HashFieldSelect(V,  scfiEn_f       , &l2l3_hash_field);
        field_sel->u.l2_l3.stag_cos = GetIpfixL2L3HashFieldSelect(V,  scosEn_f       , &l2l3_hash_field);

        field_sel->u.l2_l3.ctag_vlan = GetIpfixL2L3HashFieldSelect(V,  cvlanIdEn_f       , &l2l3_hash_field);
        field_sel->u.l2_l3.ctag_cfi = GetIpfixL2L3HashFieldSelect(V,  ccfiEn_f       , &l2l3_hash_field);
        field_sel->u.l2_l3.ctag_cos = GetIpfixL2L3HashFieldSelect(V,  ccosEn_f       , &l2l3_hash_field);
    }

    return CTC_E_NONE;
}

extern int32
sys_usw_ipfix_get_hash_field_sel(uint8 lchip, uint8 field_sel_id, uint8 key_type, ctc_ipfix_hash_field_sel_t* field_sel)
{
    int32 ret = CTC_E_NONE;
    SYS_IPFIX_INIT_CHECK(lchip);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(field_sel);
    CTC_MAX_VALUE_CHECK(field_sel_id, MCHIP_CAP(SYS_CAP_IPFIX_MAX_HASH_SEL_ID));
    if (p_usw_ipfix_master[lchip]->callbacks_get_hashsel[key_type])
    {
        CTC_ERROR_RETURN(p_usw_ipfix_master[lchip]->callbacks_get_hashsel[key_type](lchip, field_sel_id, field_sel));
    }
    else
    {
        ret = CTC_E_NOT_SUPPORT; 
    }
    return ret;
}

extern int32
sys_usw_ipfix_set_global_cfg(uint8 lchip, ctc_ipfix_global_cfg_t *ipfix_cfg)
{
    IpfixAgingTimerCtl_m aging_timer;
    IpeRouteCtl_m route_ctl;
    IpfixEngineCtl_m    ipfix_ctl;
    IpeFwdFlowHashCtl_m ipe_fwd_flow_ctl;
    EpeAclQosCtl_m epe_aclqos_ctl;
    IpeFwdCtl_m  ipe_fwd_ctl;
    EpeHeaderEditCtl_m epe_hdr_ctl;
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint64 tmp = 0;
    uint32 core_frequecy = 0;
    uint32 max_age_s = 0;
    uint32 tick_interval = 0;
    uint32 byte_cnt[2] = {0};
    uint32 pkt_cnt = 0;
    uint32 value_a = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(ipfix_cfg);
    CTC_MAX_VALUE_CHECK(ipfix_cfg->unkown_pkt_dest_type, 1);
    CTC_MAX_VALUE_CHECK(ipfix_cfg->bytes_cnt, DRV_FROM_AT(lchip)?0xFFFFFFFFFULL:0xFFFFFFFF);
    CTC_MAX_VALUE_CHECK(ipfix_cfg->pkt_cnt, DRV_FROM_AT(lchip)?0x3FFFFFFF:0x3FFFFFF);
    CTC_MAX_VALUE_CHECK(ipfix_cfg->threshold, DRV_FROM_TMM(lchip)?0xFFFFF:0xFFFF);

    pkt_cnt = (ipfix_cfg->pkt_cnt == 0) ? 0 : (ipfix_cfg->pkt_cnt - 1);

    sal_memset(&aging_timer, 0, sizeof(IpfixAgingTimerCtl_m));
    sal_memset(&ipfix_ctl, 0, sizeof(IpfixEngineCtl_m));
    sal_memset(&route_ctl, 0, sizeof(IpeRouteCtl_m));

    if(ipfix_cfg->sample_mode)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " API or some feature is not supported \n");
        return CTC_E_NOT_SUPPORT;
    }
    CTC_MAX_VALUE_CHECK(ipfix_cfg->times_interval, DRV_IS_DUET2(lchip) ? 0XFFFFF:0x3FFFFF);
    CTC_MIN_VALUE_CHECK(ipfix_cfg->times_interval,(SYS_DMA_EXPORT_IPFIX_MIN_INTERVAL));
    if (MCHIP_IPFIX(lchip)->set_global_cfg)
    {
        SYS_IPFIX_LOCK(lchip);
        ret = MCHIP_IPFIX(lchip)->set_global_cfg(lchip, ipfix_cfg);
        SYS_IPFIX_UNLOCK(lchip);
        return ret;
    }

    core_frequecy = sys_usw_get_core_freq(lchip, 0);
    max_age_s = (CTC_MAX_UINT32_VALUE / ((core_frequecy * 1000 * 1000 / DOWN_FRE_RATE))) * (p_usw_ipfix_master[lchip]->max_ptr/(DRV_IS_DUET2(lchip)?4:1) + 1);
    if (max_age_s < ipfix_cfg->aging_interval)
    {
        return CTC_E_INVALID_PARAM;
    }

    tmp = (((uint64)core_frequecy * 1000 *1000)/DOWN_FRE_RATE);
    tmp *= ipfix_cfg->aging_interval;
    tick_interval = tmp / (p_usw_ipfix_master[lchip]->max_ptr/(DRV_IS_DUET2(lchip)?4:1) + 1);
    SYS_IPFIX_LOCK(lchip);
    p_usw_ipfix_master[lchip]->aging_interval = ipfix_cfg->aging_interval;
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER, 1);
    SYS_IPFIX_UNLOCK(lchip);
    if ((tick_interval == 0) && (ipfix_cfg->aging_interval !=0))
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"aging_interval is 0! \n");
        return CTC_E_INVALID_PARAM;
    }

    cmd = DRV_IOR( IpfixAgingTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));
    SetIpfixAgingTimerCtl(V, agingUpdEn_f, &aging_timer, (ipfix_cfg->aging_interval !=0));
    SetIpfixAgingTimerCtl(V, cpuAgingEn_f, &aging_timer, !!ipfix_cfg->sw_learning_en);

    if (ipfix_cfg->aging_interval)
    {
        SetIpfixAgingTimerCtl(V, agingInterval_f, &aging_timer, tick_interval);
    }

    cmd = DRV_IOW( IpfixAgingTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));
    cmd = DRV_IOW( IpfixAgingTimerCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));
    cmd = DRV_IOW( IpfixAgingTimerCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer));

    byte_cnt[0] = (ipfix_cfg->bytes_cnt) & 0xffffffff;
    cmd = DRV_IOR( IpfixEngineCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));
    SetIpfixEngineCtl(A, byteCntWraparoundThre_f, &ipfix_ctl, byte_cnt);

    value_a = !!ipfix_cfg->conflict_export;
    cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_ipfixConflictPktLogEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    cmd = DRV_IOW(EpeHeaderEditCtl_t,EpeHeaderEditCtl_ipfixConflictPktLogEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

    SetIpfixEngineCtl(V, pktCntWraparoundThre_f , &ipfix_ctl, pkt_cnt);
    SetIpfixEngineCtl(V, ignorTcpClose_f , &ipfix_ctl, ((ipfix_cfg->tcp_end_detect_en)?0:1));
    SetIpfixEngineCtl(V, tsWraparoundThre_f , &ipfix_ctl, ipfix_cfg->times_interval);  /*granularity is 1ms*/
    SetIpfixEngineCtl(V, isCpuSetFlowKeyMode_f , &ipfix_ctl, ipfix_cfg->sw_learning_en);
    SetIpfixEngineCtl(V, unknownPktDestIsVlanId_f, &ipfix_ctl, ipfix_cfg->unkown_pkt_dest_type);
    SetIpfixEngineCtl(V, newFlowExportModeForIpfix_f  , &ipfix_ctl, !!ipfix_cfg->new_flow_export_en);
    SetIpfixEngineCtl(V, recordLatestDiscardType_f , &ipfix_ctl, 1);
    if(ipfix_cfg->threshold)
    {
        SetIpfixEngineCtl(V, flowUseageIntEnable_f, &ipfix_ctl, 0x3);
    }
    else
    {
        SetIpfixEngineCtl(V, flowUseageIntEnable_f, &ipfix_ctl, 0);
    }
    SetIpfixEngineCtl(V, flowCountThreshold_f, &ipfix_ctl, ipfix_cfg->threshold);
    SetIpfixEngineCtl(V, forceEgrIpfixUseJitterMonitor_f, &ipfix_ctl, ipfix_cfg->latency_type);

    cmd = DRV_IOW( IpfixEngineCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));
    cmd = DRV_IOW( IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));
    cmd = DRV_IOW( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));

    if(0 == ipfix_cfg->conflict_cnt)
    {
        cmd = DRV_IOW( IpfixMissPktCounter_t, IpfixMissPktCounter_missPktCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_cfg->conflict_cnt));
        cmd = DRV_IOW( IpfixMissPktCounter0_t, IpfixMissPktCounter0_missPktCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_cfg->conflict_cnt));
        cmd = DRV_IOW( IpfixMissPktCounter1_t, IpfixMissPktCounter1_missPktCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_cfg->conflict_cnt));
    }
    cmd = DRV_IOW(IpeFwdFlowHashCtl_t, IpeFwdFlowHashCtl_ipfixDestUseLagId_f);
    value_a = ipfix_cfg->dest_port_type ?0:1;
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

    cmd = DRV_IOR(IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl));
    SetIpeFwdFlowHashCtl(V, mirrorPktEnableIpfix_f, &ipe_fwd_flow_ctl, ipfix_cfg->mirror_pkt_enable ? 1:0);
    SetIpeFwdFlowHashCtl(V, mirrorPktEnableMicroflowPolicing_f, &ipe_fwd_flow_ctl, ipfix_cfg->mirror_pkt_enable ? 1:0);
    cmd = DRV_IOW(IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl));

    cmd = DRV_IOR(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_aclqos_ctl));
    SetEpeAclQosCtl(V, mirrorPktEnableIpfix_f, &epe_aclqos_ctl, ipfix_cfg->mirror_pkt_enable ? 1:0);
    SetEpeAclQosCtl(V, mirrorPktEnableMicroflowPolicing_f, &epe_aclqos_ctl, ipfix_cfg->mirror_pkt_enable ? 1:0);
    cmd = DRV_IOW(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_aclqos_ctl));
    cmd = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_ctl));
    SetIpeFwdCtl(V, skipSpanPacketLoop_f, &ipe_fwd_ctl, ipfix_cfg->mirror_pkt_enable ? 0:1);
    cmd = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_ctl));
    cmd = DRV_IOR(EpeHeaderEditCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_hdr_ctl));
    SetEpeHeaderEditCtl(V, skipSpanPacketLoop_f, &epe_hdr_ctl, ipfix_cfg->mirror_pkt_enable ? 0:1);
    cmd = DRV_IOW(EpeHeaderEditCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_hdr_ctl));

    return CTC_E_NONE;
}



extern int32
sys_usw_ipfix_get_global_cfg(uint8 lchip, ctc_ipfix_global_cfg_t *ipfix_cfg)
{
    IpfixAgingTimerCtl_m aging_timer;
    IpfixEngineCtl_m    ipfix_ctl;
    IpeRouteCtl_m route_ctl;
    IpeFwdCtl_m   ipe_fwd_ctl;
    IpeFwdFlowHashCtl_m ipe_fwd_flow_ctl;

    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 miss_pkt_cnt = 0;
    uint32 byte_cnt[2] = {0};
    uint32 value = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(ipfix_cfg);

    sal_memset(&aging_timer, 0, sizeof(IpfixAgingTimerCtl_m));
    sal_memset(&ipfix_ctl, 0, sizeof(IpfixEngineCtl_m));
    sal_memset(&ipe_fwd_ctl,0,sizeof(ipe_fwd_ctl));

    if (MCHIP_IPFIX(lchip)->get_global_cfg)
    {
        CTC_ERROR_RETURN(MCHIP_IPFIX(lchip)->get_global_cfg(lchip, ipfix_cfg));
        return CTC_E_NONE;
    }

    SYS_IPFIX_LOCK(lchip);
    cmd = DRV_IOR( IpeRouteCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &route_ctl), ret, error_pro);

    cmd = DRV_IOR( IpfixAgingTimerCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_timer), ret, error_pro);

    ipfix_cfg->aging_interval = p_usw_ipfix_master[lchip]->aging_interval;
    cmd = DRV_IOR( IpfixEngineCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl), ret, error_pro);
    GetIpfixEngineCtl(A, byteCntWraparoundThre_f, &ipfix_ctl, byte_cnt);

    ipfix_cfg->bytes_cnt = 0;
    ipfix_cfg->bytes_cnt = byte_cnt[1];
    ipfix_cfg->bytes_cnt <<= 32;
    ipfix_cfg->bytes_cnt |= byte_cnt[0];
    ipfix_cfg->sw_learning_en = GetIpfixEngineCtl(V, isCpuSetFlowKeyMode_f , &ipfix_ctl);
    ipfix_cfg->pkt_cnt = GetIpfixEngineCtl(V, pktCntWraparoundThre_f , &ipfix_ctl)+1;
    ipfix_cfg->times_interval = GetIpfixEngineCtl(V, tsWraparoundThre_f, &ipfix_ctl);  /*1s*/
    ipfix_cfg->tcp_end_detect_en = !GetIpfixEngineCtl(V, ignorTcpClose_f, &ipfix_ctl);
    ipfix_cfg->new_flow_export_en = GetIpfixEngineCtl(V, newFlowExportModeForIpfix_f, &ipfix_ctl);
    ipfix_cfg->unkown_pkt_dest_type = GetIpfixEngineCtl(V, unknownPktDestIsVlanId_f, &ipfix_ctl);
    ipfix_cfg->threshold = GetIpfixEngineCtl(V, flowCountThreshold_f, &ipfix_ctl);
    ipfix_cfg->latency_type = GetIpfixEngineCtl(V, forceEgrIpfixUseJitterMonitor_f, &ipfix_ctl);

    cmd = DRV_IOR(IpeFwdCtl_t,DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_ctl), ret, error_pro);

    ipfix_cfg->conflict_export = (uint8)GetIpeFwdCtl(V,ipfixConflictPktLogEn_f,&ipe_fwd_ctl);
    if(DRV_IS_DUET2(lchip))
    {
        cmd = DRV_IOR(IpfixMissPktCounter_t, IpfixMissPktCounter_missPktCount_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &(ipfix_cfg->conflict_cnt)), ret, error_pro);
    }
    else
    {
        cmd = DRV_IOR(IpfixMissPktCounter0_t, IpfixMissPktCounter0_missPktCount_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &(miss_pkt_cnt)), ret, error_pro);
        cmd = DRV_IOR(IpfixMissPktCounter1_t, IpfixMissPktCounter1_missPktCount_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &(ipfix_cfg->conflict_cnt)), ret, error_pro);
        ipfix_cfg->conflict_cnt += miss_pkt_cnt;
    }
    cmd = DRV_IOR(IpeFwdFlowHashCtl_t, IpeFwdFlowHashCtl_ipfixDestUseLagId_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value), ret, error_pro);
    ipfix_cfg->dest_port_type = value ? 0:1;

    cmd = DRV_IOR(IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl), ret, error_pro);
    ipfix_cfg->mirror_pkt_enable = GetIpeFwdFlowHashCtl(V, mirrorPktEnableIpfix_f, &ipe_fwd_flow_ctl);
error_pro:
    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}

extern int32
sys_usw_ipfix_set_flow_cfg(uint8 lchip, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint32  cmd = 0;
    uint32  sample_enable = 0;
    uint32  sample_profile_index = 0;
    uint8   flow_type = 0;
    uint32  step = 0;
    int32   ret;
    uint32  cfg_table_id;
    uint32  sample_cfg_table_id;

    DsIngressIpfixConfig_m  ipfix_cfg;
    IpfixIngSamplingProfile_m  ipfix_sampling_cfg;

    sys_ipfix_sample_profile_t* p_get_sample_prf;
    sys_ipfix_sample_profile_t new_sample_prf;
    sys_ipfix_sample_profile_t old_sample_prf;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_flow_cfg);

    sal_memset(&ipfix_cfg, 0, sizeof(ipfix_cfg));
    sal_memset(&ipfix_sampling_cfg, 0, sizeof(ipfix_sampling_cfg));
    sal_memset(&old_sample_prf, 0, sizeof(old_sample_prf));

    CTC_MAX_VALUE_CHECK(p_flow_cfg->dir, CTC_EGRESS);

    CTC_MAX_VALUE_CHECK(p_flow_cfg->sample_mode, 1);
    CTC_MAX_VALUE_CHECK(p_flow_cfg->sample_type, 1);
    CTC_MAX_VALUE_CHECK(p_flow_cfg->flow_type, 0x3F);
    if(((p_flow_cfg->flow_type &CTC_IPFIX_FLOW_TYPE_NON_DISCARD_PACKET) & ((p_flow_cfg->flow_type &CTC_IPFIX_FLOW_TYPE_DISCARD_PACKET)>> 1))\
        ||(((p_flow_cfg->flow_type &CTC_IPFIX_FLOW_TYPE_NON_BURST)>>2) & ((p_flow_cfg->flow_type &CTC_IPFIX_FLOW_TYPE_BURST)>> 3))\
        ||(((p_flow_cfg->flow_type &CTC_IPFIX_FLOW_TYPE_NON_LATENCY)>>4) & ((p_flow_cfg->flow_type &CTC_IPFIX_FLOW_TYPE_LATENCY)>>5)))
    {
        return CTC_E_INVALID_PARAM;
    }

    if ((p_flow_cfg->sample_mode == 0) && (p_flow_cfg->sample_interval > 0x1fff))
    {
        return CTC_E_INVALID_PARAM;
    }
    if ((p_flow_cfg->sample_mode == 1) && (p_flow_cfg->sample_interval > 400))
    {
        return CTC_E_INVALID_PARAM;
    }

    if(p_flow_cfg->sample_interval == 1)
    {
        p_flow_cfg->sample_interval =0;
    }

    if (DRV_IS_DUET2(lchip))
    {
        if (p_flow_cfg->dir == CTC_INGRESS)
        {
            cfg_table_id = DsIngressIpfixConfig_t;
            sample_cfg_table_id = IpfixIngSamplingProfile_t;
        }
        else
        {
            cfg_table_id = DsEgressIpfixConfig_t;
            sample_cfg_table_id = IpfixEgrSamplingProfile_t;
        }
    }
    else
    {
        if (p_flow_cfg->dir == CTC_INGRESS)
        {
            cfg_table_id = DsIpfixConfig0_t;
            sample_cfg_table_id = IpfixSamplingProfile0_t;
        }
        else
        {
            cfg_table_id = DsIpfixConfig1_t;
            sample_cfg_table_id = IpfixSamplingProfile1_t;
        }
    }
    cmd = DRV_IOR( cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg));
    cmd = DRV_IOR( sample_cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_sampling_cfg));

    sample_enable = GetDsIngressIpfixConfig(V, samplingEn_f, &ipfix_cfg);  /* Dt2, TM DsIngressIpfixConfig struct are same */
    sample_profile_index = GetDsIngressIpfixConfig(V, samplingProfileIndex_f, &ipfix_cfg);

    step = IpfixIngSamplingProfile_array_1_ingSamplingPktInterval_f - IpfixIngSamplingProfile_array_0_ingSamplingPktInterval_f;

    SYS_IPFIX_LOCK(lchip);

    if (MCHIP_IPFIX(lchip)->set_flow_cfg)
    {
        CTC_ERROR_RETURN_WITH_UNLOCK(MCHIP_IPFIX(lchip)->set_flow_cfg(lchip, p_flow_cfg), p_usw_ipfix_master[lchip]->p_mutex);
        SYS_IPFIX_UNLOCK(lchip);
        return CTC_E_NONE;
    }

    if(sample_enable)
    {
        old_sample_prf.dir = p_flow_cfg->dir;
        old_sample_prf.mode = GetIpfixIngSamplingProfile(V, \
                                    array_0_ingSamplingMode_f+step*sample_profile_index, &ipfix_sampling_cfg);
        if(p_flow_cfg->dir == CTC_INGRESS)
        {
            old_sample_prf.interval = p_usw_ipfix_master[lchip]->sip_interval[sample_profile_index];
        }
        else
        {
            old_sample_prf.interval = p_usw_ipfix_master[lchip]->sip_interval[sample_profile_index+MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE)];
        }
        old_sample_prf.mode |= GetIpfixIngSamplingProfile(V, \
                                    array_0_ingCountBasedSamplingMode_f+step*sample_profile_index, &ipfix_sampling_cfg) << 1;
    }

    if(p_flow_cfg->sample_interval != 0) /*add or update*/
    {
        uint16 drv_interval = 0;
        new_sample_prf.dir = p_flow_cfg->dir;
        new_sample_prf.interval = p_flow_cfg->sample_interval;
        new_sample_prf.mode = (!!p_flow_cfg->sample_type << 1) | (!!p_flow_cfg->sample_mode);

        ret = ctc_spool_add(p_usw_ipfix_master[lchip]->sample_spool, &new_sample_prf, &old_sample_prf, &p_get_sample_prf);
        if(ret)
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"add sample spool error, %%ret=%d\n", ret);
            SYS_IPFIX_UNLOCK(lchip);
            return ret;
        }
        if(p_flow_cfg->dir == CTC_INGRESS)
        {
            p_usw_ipfix_master[lchip]->sip_interval[p_get_sample_prf->ad_index] = p_flow_cfg->sample_interval;
        }
        else
        {
            p_usw_ipfix_master[lchip]->sip_interval[p_get_sample_prf->ad_index+MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE)] = p_flow_cfg->sample_interval;
        }
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER, 1);
        /*write hw*/
        sample_profile_index = p_get_sample_prf->ad_index;
        _sys_usw_ipfix_sample_interval_convert(lchip, p_get_sample_prf, &drv_interval);
        SetIpfixIngSamplingProfile(V, array_0_ingSamplingPktInterval_f+step*sample_profile_index, &ipfix_sampling_cfg, drv_interval);
        SetIpfixIngSamplingProfile(V, array_0_ingSamplingMode_f+step*sample_profile_index, &ipfix_sampling_cfg, p_get_sample_prf->mode&0x01);
        SetIpfixIngSamplingProfile(V, array_0_ingCountBasedSamplingMode_f+step*sample_profile_index, &ipfix_sampling_cfg, (p_get_sample_prf->mode>>1)&0x01);

        SetDsIngressIpfixConfig(V, samplingProfileIndex_f, &ipfix_cfg, p_get_sample_prf->ad_index);
        SetDsIngressIpfixConfig(V, samplingEn_f, &ipfix_cfg, 1);
    }
    else if(sample_enable)
    {
        ret = ctc_spool_remove(p_usw_ipfix_master[lchip]->sample_spool, &old_sample_prf, &p_get_sample_prf);
        if(ret)
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"remove sample spool error, %%ret=%d\n", ret);
            SYS_IPFIX_UNLOCK(lchip);
            return ret;
        }
        /*write hw*/
        SetDsIngressIpfixConfig(V, samplingProfileIndex_f, &ipfix_cfg, 0);
        SetDsIngressIpfixConfig(V, samplingEn_f, &ipfix_cfg, 0);
    }

    if(CTC_IPFIX_FLOW_TYPE_ALL_PACKET == p_flow_cfg->flow_type)
    {
        flow_type = 0;
    }
    else if(CTC_IPFIX_FLOW_TYPE_NON_DISCARD_PACKET == p_flow_cfg->flow_type)
    {
        flow_type = 1;
    }
    else if(CTC_IPFIX_FLOW_TYPE_DISCARD_PACKET == p_flow_cfg->flow_type)
    {
        flow_type = 2;
    }
    SetDsIngressIpfixConfig(V, flowType_f, &ipfix_cfg, flow_type);

    SetDsIngressIpfixConfig(V, sessionNumLimitEn_f, &ipfix_cfg, !!p_flow_cfg->learn_disable);
    SetDsIngressIpfixConfig(V, tcpSessionEndDetectDisable_f, &ipfix_cfg, !!p_flow_cfg->tcp_end_detect_disable);
    /*now only support dropped packet*/
    SetDsIngressIpfixConfig(V, ipfixAdMode_f, &ipfix_cfg, 1);
    SetDsIngressIpfixConfig(V, ipfixMirrorCount_f, &ipfix_cfg, p_flow_cfg->log_pkt_count);

    cmd = DRV_IOW(cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN_WITH_UNLOCK(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg), p_usw_ipfix_master[lchip]->p_mutex);
    cmd = DRV_IOW( sample_cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN_WITH_UNLOCK(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_sampling_cfg), p_usw_ipfix_master[lchip]->p_mutex);

    SYS_IPFIX_UNLOCK(lchip);
    return CTC_E_NONE;
}

extern int32
sys_usw_ipfix_get_flow_cfg(uint8 lchip, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint32 cmd = 0;
    uint32  samping_idx = 0;
    uint8 flow_type = 0;
    uint8 step = 0;
    uint32  cfg_table_id;
    uint32  sample_cfg_table_id;
    IpfixIngSamplingProfile_m  ipfix_ing_sampleing_cfg;
    DsIngressIpfixConfig_m  ipfix_cfg;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_flow_cfg);
    CTC_MAX_VALUE_CHECK(p_flow_cfg->dir, CTC_EGRESS);

    SYS_IPFIX_LOCK(lchip);

    if (MCHIP_IPFIX(lchip)->get_flow_cfg)
    {
        CTC_ERROR_RETURN_WITH_UNLOCK(MCHIP_IPFIX(lchip)->get_flow_cfg(lchip, p_flow_cfg), p_usw_ipfix_master[lchip]->p_mutex);
        SYS_IPFIX_UNLOCK(lchip);
        return CTC_E_NONE;
    }

    step = IpfixIngSamplingProfile_array_1_ingSamplingPktInterval_f - IpfixIngSamplingProfile_array_0_ingSamplingPktInterval_f;

    if (p_flow_cfg->dir == CTC_INGRESS)
    {

        if (DRV_IS_DUET2(lchip))
        {
            cfg_table_id = DsIngressIpfixConfig_t;
            sample_cfg_table_id = IpfixIngSamplingProfile_t;
        }
        else
        {
            cfg_table_id = DsIpfixConfig0_t;
            sample_cfg_table_id = IpfixSamplingProfile0_t;
        }
    }
    else
    {
        if (DRV_IS_DUET2(lchip))
        {
            cfg_table_id = DsEgressIpfixConfig_t;
            sample_cfg_table_id = IpfixEgrSamplingProfile_t;
        }
        else
        {

            cfg_table_id = DsIpfixConfig1_t;
            sample_cfg_table_id = IpfixSamplingProfile1_t;

        }
    }
    cmd = DRV_IOR( sample_cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN_WITH_UNLOCK(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ing_sampleing_cfg), p_usw_ipfix_master[lchip]->p_mutex);
    cmd = DRV_IOR( cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN_WITH_UNLOCK(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg), p_usw_ipfix_master[lchip]->p_mutex);

    p_flow_cfg->tcp_end_detect_disable = GetDsIngressIpfixConfig(V, tcpSessionEndDetectDisable_f, &ipfix_cfg);
    p_flow_cfg->learn_disable = GetDsIngressIpfixConfig(V, sessionNumLimitEn_f, &ipfix_cfg);
    p_flow_cfg->log_pkt_count = GetDsIngressIpfixConfig(V, ipfixMirrorCount_f, &ipfix_cfg);
    flow_type = GetDsIngressIpfixConfig(V, flowType_f, &ipfix_cfg);
    if(0 == flow_type)
    {
        p_flow_cfg->flow_type = CTC_IPFIX_FLOW_TYPE_ALL_PACKET;
    }
    else if(1 == flow_type)
    {
        p_flow_cfg->flow_type = CTC_IPFIX_FLOW_TYPE_NON_DISCARD_PACKET;
    }
    else if(2 == flow_type)
    {
        p_flow_cfg->flow_type = CTC_IPFIX_FLOW_TYPE_DISCARD_PACKET;
    }


    if(GetDsIngressIpfixConfig(V, samplingEn_f, &ipfix_cfg))
    {
        samping_idx = GetDsIngressIpfixConfig(V, samplingProfileIndex_f, &ipfix_cfg);
        p_flow_cfg->sample_mode = GetIpfixIngSamplingProfile(V, array_0_ingSamplingMode_f + samping_idx*step, &ipfix_ing_sampleing_cfg);
        p_flow_cfg->sample_type = GetIpfixIngSamplingProfile(V, array_0_ingCountBasedSamplingMode_f+samping_idx*step, &ipfix_ing_sampleing_cfg);

        if(p_flow_cfg->dir == CTC_INGRESS)
        {
            p_flow_cfg->sample_interval = p_usw_ipfix_master[lchip]->sip_interval[samping_idx];
        }
        else
        {
            p_flow_cfg->sample_interval = p_usw_ipfix_master[lchip]->sip_interval[samping_idx+MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE)];
        }
    }

    SYS_IPFIX_UNLOCK(lchip);
    return CTC_E_NONE;
}

extern int32
sys_usw_ipfix_register_cb(uint8 lchip, ctc_ipfix_fn_t callback,void *userdata)
{
    uintptr chip_id = lchip;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    
    SYS_IPFIX_INIT_CHECK(lchip);
    
    SYS_IPFIX_LOCK(lchip);
    if(!callback)
    {
         p_usw_ipfix_master[lchip]->ipfix_cb = _sys_usw_ipfix_process_isr;
         p_usw_ipfix_master[lchip]->user_data = (void*)chip_id;
    }
    else
    {
         p_usw_ipfix_master[lchip]->ipfix_cb = callback;
         p_usw_ipfix_master[lchip]->user_data = userdata;
    }

    SYS_IPFIX_UNLOCK(lchip);
    return CTC_E_NONE;
}
#if 0
int32
sys_usw_ipfix_get_cb(uint8 lchip, void **cb, void** user_data)
{
    SYS_IPFIX_INIT_CHECK(lchip);

    *cb = p_usw_ipfix_master[lchip]->ipfix_cb;
    *user_data = p_usw_ipfix_master[lchip]->user_data;

    return CTC_E_NONE;
}
#endif
int32
sys_usw_ipfix_npm_im_flow_en(uint8 lchip, uint8 enable)
{
    ctc_ipfix_flow_cfg_t flow_cfg;
    ctc_ipfix_global_cfg_t ipfix_cfg;
    ctc_ipfix_hash_field_sel_t field_sel;
    ds_t      ds;
    uint32 cmd = 0;

    sal_memset(&flow_cfg, 0, sizeof(flow_cfg));
    sal_memset(&ipfix_cfg, 0, sizeof(ipfix_cfg));
    sal_memset(&field_sel, 0, sizeof(field_sel));

    flow_cfg.profile_id = MCHIP_CAP(SYS_CAP_NPM_IPFIX_CFG_PRF_ID);
    flow_cfg.dir = CTC_EGRESS;
    flow_cfg.flow_type = 0;
    flow_cfg.deny_export_reason_bmp = 0;
    CTC_ERROR_RETURN(sys_usw_ipfix_set_flow_cfg(lchip, &flow_cfg));

    sal_memset(&flow_cfg, 0, sizeof(flow_cfg));
    flow_cfg.profile_id = MCHIP_CAP(SYS_CAP_NPM_IPFIX_CFG_PRF_ID);
    flow_cfg.dir = CTC_INGRESS;
    flow_cfg.flow_type = 0;
    CTC_BIT_SET(flow_cfg.suppress_reason_bmp, CTC_IPFIX_REASON_LAST_TS_OVERFLOW);
    CTC_ERROR_RETURN(sys_usw_ipfix_set_flow_cfg(lchip, &flow_cfg));

    ipfix_cfg.max_export_entry_num = enable?1:0;
    ipfix_cfg.times_interval = SYS_DMA_EXPORT_IPFIX_MIN_INTERVAL;
    CTC_ERROR_RETURN(sys_usw_ipfix_set_global_cfg(lchip, &ipfix_cfg));

    field_sel.field_sel_id = MCHIP_CAP(SYS_CAP_NPM_IPFIX_HASH_FIELD_ID);
    field_sel.key_type = CTC_IPFIX_KEY_HASH_MPLS;
    field_sel.u.mpls.metadata = 1;
    CTC_ERROR_RETURN(sys_usw_ipfix_set_hash_field_sel(lchip, &field_sel));

    cmd = DRV_IOR(IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetIpfixEngineCtl1(V, maxLatencyExportThreCheckEn_f, &ds, enable?1:0);

    SetIpfixEngineCtl1(V, maxJitterExportThreshold_f, &ds, 0);

    cmd = DRV_IOW( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    cmd = DRV_IOR(TsEngineRefMsNsThreshold_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetTsEngineRefMsNsThreshold(V, msNsThreshold_f, &ds, enable?32:1000000);
    cmd = DRV_IOW( TsEngineRefMsNsThreshold_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    return CTC_E_NONE;
}

int32
sys_usw_ipfix_ftm_cb(uint8 lchip, sys_ftm_specs_info_t* specs_info)
{
    CTC_PTR_VALID_CHECK(specs_info);
    SYS_IPFIX_INIT_CHECK(lchip);

    specs_info->used_size = sys_usw_ipfix_get_flow_cnt(lchip);

    return CTC_E_NONE;
}
uint32
sys_usw_ipfix_get_flow_cnt(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 cnt = 0;

    SYS_IPFIX_INIT_CHECK(lchip);
    if (DRV_IS_DUET2(lchip) || (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        cmd = DRV_IOR( IpfixFlowEntryCounter_t, IpfixFlowEntryCounter_flowEntryCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &cnt));
    }
    else
    {
        uint32 egress_entry_cnt = 0;
        cmd = DRV_IOR( IpfixFlowEntryCounter0_t, IpfixFlowEntryCounter0_flowEntryCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &cnt));

        cmd = DRV_IOR( IpfixFlowEntryCounter1_t, IpfixFlowEntryCounter1_flowEntryCount_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &egress_entry_cnt));

        cnt += egress_entry_cnt;
    }

    return cnt;
}

int32
_sys_usw_ipfix_get_str(uint32 flag, char* p_str)
{
    if (flag&CTC_IPFIX_DATA_L2_MCAST_DETECTED)
    {
        sal_strcat((char*)p_str, "L2-Mcast ");
    }
    if (flag&CTC_IPFIX_DATA_L3_MCAST_DETECTED)
    {
        sal_strcat((char*)p_str, "L3-Mcast ");
    }
    if (flag&CTC_IPFIX_DATA_BCAST_DETECTED)
    {
        sal_strcat((char*)p_str, "Bcast ");
    }
    if (flag&CTC_IPFIX_DATA_APS_DETECTED)
    {
        sal_strcat((char*)p_str, "Aps ");
    }
    if (flag&CTC_IPFIX_DATA_ECMP_DETECTED)
    {
        sal_strcat((char*)p_str, "ECMP ");
    }
    if (flag&CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED)
    {
        sal_strcat((char*)p_str, "Frag ");
    }
    if (flag&CTC_IPFIX_DATA_DROP_DETECTED)
    {
        sal_strcat((char*)p_str, "Drop ");
    }
    if (flag&CTC_IPFIX_DATA_LINKAGG_DETECTED)
    {
        sal_strcat((char*)p_str, "Linkagg ");
    }
    if (flag&CTC_IPFIX_DATA_TTL_CHANGE)
    {
        sal_strcat((char*)p_str, "TTL-Change ");
    }
    if (flag&CTC_IPFIX_DATA_UNKNOW_PKT_DETECTED)
    {
        sal_strcat((char*)p_str, "Unkown-Pkt ");
    }
    if (flag&CTC_IPFIX_DATA_CVLAN_TAGGED)
    {
        sal_strcat((char*)p_str, "Cvlan-Valid ");
    }
    if (flag&CTC_IPFIX_DATA_SVLAN_TAGGED)
    {
        sal_strcat((char*)p_str, "Svlan-Valid ");
    }
    if (flag&CTC_IPFIX_DATA_SRC_CID_VALID)
    {
        sal_strcat((char*)p_str, "Src Cid Valid");
    }
    if (flag&CTC_IPFIX_DATA_DST_CID_VALID)
    {
        sal_strcat((char*)p_str, "Dest Cid Valid");
    }
    if (flag&CTC_IPFIX_DATA_MFP_VALID)
    {
        sal_strcat((char*)p_str, "MFP Valid");
    }
    return CTC_E_NONE;
}

void
_sys_usw_ipfix_process_isr(ctc_ipfix_data_t* info, void* userdata)
{
    uint8 loop_i = 0;
    char str[256] = {0};
    char* reason_str[22] = {"NO Export","Expired","Tcp Close", "PktCnt Overflow","ByteCnt Overflow","Ts Overflow",\
        "Hash Conflict","New Flow", "Dest Change", "Jitter Overflow", "Latency Overflow", "TTL Change", "Drop Packet Overflow",\
        "Drop Reason Change", "Tc Mark", "Dump","Buffer Drop","Burst Event","Latency Event","Burst Count Overflow",\
        "Latency Count Overflow","Buffer Drop Overflow"};
    uint32 tempip = 0;
    char buf[CTC_IPV6_ADDR_STR_LEN];
    uint32 ipv6_address[4] = {0, 0, 0, 0};
    uint8 index = 0;
    uint32 cmd = 0;
    ds_t    ipfix_ctl;
    uint8 iscpu_set_mode = 0;
    uint8 lchip = (uintptr)userdata;
    const char* p_drop_str = NULL;
    ctc_ipfix_data_t* p_info = info;
    ctc_field_key_t* p_field_list = p_info->flex_key.field_list;
    uint32 tmp_field_num = p_info->flex_key.field_num;
    ctc_xdata_field_t* p_xdata_list = p_info->xdata.fields;
    uint32 tmp_xdata_num = p_info->xdata.num;
    if (NULL == info)
    {
        return;
    }
    sal_memset(&ipfix_ctl, 0, sizeof(ds_t));
    cmd = DRV_IOR((DRV_FROM_TMM(lchip)? IpfixEngineCtl0_t : IpfixEngineCtl_t), DRV_ENTRY_FLAG);
    (DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));
    iscpu_set_mode = DRV_FROM_TMM(lchip) ? GetIpfixEngineCtl0(V, isCpuSetFlowKeyMode_f , &ipfix_ctl) : GetIpfixEngineCtl(V, isCpuSetFlowKeyMode_f , &ipfix_ctl);

    do {
        str[0] = '\0';
        _sys_usw_ipfix_get_str(info->flags, str);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"\n********Ipfix Export Information******** \n");
        if(DRV_FROM_AT(lchip))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "PP Bmp",info->pp_bmp);
        }
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %d\n", "Key_type",info->key_type);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Key_index",info->key_index);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %s\n", "Dir",(info->dir)?"Egress":"Ingress");
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %s\n", "Export_reason", reason_str[info->export_reason]);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Start_timestamp", (info->start_timestamp));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Last_timestamp", (info->last_timestamp));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%"PRIx64"\n", "Byte_count", (info->byte_count));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Pkt_count", (info->pkt_count));
        p_drop_str = sys_usw_register_get_reason_desc(lchip, info->drop_reason[0]);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %s\n", "Drop Reason0", p_drop_str);
        p_drop_str = sys_usw_register_get_reason_desc(lchip, info->drop_reason[1]);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %s\n", "Drop Reason1", p_drop_str);

        if (DRV_FROM_TMM(lchip))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Fid", (info->fid));

            /*Ingress export infomation*/
        if(info->drop_reason_bmp[0] || info->drop_reason_bmp[1])
        {
            for(loop_i=0; loop_i<CTC_DROP_MAX; loop_i++)
            {
                if(CTC_BMP_ISSET(info->drop_reason_bmp, loop_i))
                {
                    p_drop_str = sys_usw_register_get_reason_desc(lchip, loop_i);
                    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %s\n", "Drop Reason", p_drop_str);
                }
            }
        }
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Drop Pkt Cnt0", (info->drop_pkt_cnt[0]));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Drop Pkt Cnt1", (info->drop_pkt_cnt[1]));
            /*MMU export infomation*/
            if (DRV_FROM_AT(lchip))
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Dest Port", (info->dest_port));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Queue Id", (info->queue_id));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Queue Count", (info->queue_count));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Burst State", (info->burst_state));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Min Queue Count", (info->min_queue_count));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Max Queue Count", (info->max_queue_count));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Buffer drop(Igr)", (info->buf_drop_reason[0]));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Buffer drop(Egr)", (info->buf_drop_reason[1]));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Buffer drop count", (info->buf_drop_cnt));
            }
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Udf Id", (info->udf_id));
            if (info->key_type == CTC_IPFIX_KEY_HASH_UDF)
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", "Udf Data", info->udf[0],
                                      info->udf[1], info->udf[2], info->udf[3], info->udf[4], info->udf[5], info->udf[6], info->udf[7], info->udf[8], info->udf[9], info->udf[10],
                                      info->udf[11], info->udf[12], info->udf[13], info->udf[14], info->udf[15]);
            }
            else if (info->key_type == CTC_IPFIX_KEY_HASH_UDF_SINGLE)
            {

                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", "Udf Data", info->udf[0],
                                      info->udf[1], info->udf[2], info->udf[3], info->udf[4], info->udf[5], info->udf[6], info->udf[7], info->udf[8], info->udf[9]);
            }

             /*Egress export infomation*/
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Avg_latency", (info->avg_latency));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Last_latency", (info->last_latency));
        }
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Pkt_count(Egr)", (info->e_pkt_count));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%"PRIx64"\n", "Byte_count(Egr)", (info->e_byte_count));
            if (info->e_drop_reason_bmp[0] || info->e_drop_reason_bmp[1])
            {
                for (loop_i = 0; loop_i < CTC_DROP_MAX; loop_i++)
                {
                    if (CTC_BMP_ISSET(info->e_drop_reason_bmp, loop_i))
                    {
                        p_drop_str = sys_usw_register_get_reason_desc(lchip, loop_i);
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %s\n", "Drop Reason(Egr)", p_drop_str);
                    }
                }
            }
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Drop Pkt Cnt0(Egr)", (info->e_drop_pkt_cnt[0]));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Drop Pkt Cnt1(Egr)", (info->e_drop_pkt_cnt[1]));
            p_drop_str = sys_usw_register_get_reason_desc(lchip, info->e_drop_reason[0]);
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %s\n", "Drop Reason0(Egr)", p_drop_str);
            p_drop_str = sys_usw_register_get_reason_desc(lchip, info->e_drop_reason[1]);
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %s\n", "Drop Reason1(Egr)", p_drop_str);
        }
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %d\n", "Avg_jitter", (info->avg_jitter));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Min_ttl", (info->min_ttl));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Max_ttl", (info->max_ttl));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Tcp flags(action)", (info->tcp_flags));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x(%s)\n", "Flag", (info->flags), str);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Port_type", (info->port_type));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Logic-port", (info->logic_port));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Gport", (info->gport));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Svlan", (info->svlan));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Svlan_prio", (info->svlan_prio));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Svlan_cfi", (info->svlan_cfi));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Cvlan", (info->cvlan));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Cvlan_prio", (info->cvlan_prio));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Cvlan_cfi", (info->cvlan_cfi));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Ether_type", (info->ether_type));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Source cid", (info->src_cid));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Dest cid", (info->dst_cid));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Profile ID", (info->profile_id));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Hash field sel ID", (info->field_sel_id));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s:%.4x.%.4x.%.4x \n", "Macsa",
            sal_ntohs(*(unsigned short*)&info->src_mac[0]),  sal_ntohs(*(unsigned short*)&info->src_mac[2]), sal_ntohs(*(unsigned short*)&info->src_mac[4]));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s:%.4x.%.4x.%.4x \n", "Macda",
            sal_ntohs(*(unsigned short*)&info->dst_mac[0]),  sal_ntohs(*(unsigned short*)&info->dst_mac[2]), sal_ntohs(*(unsigned short*)&info->dst_mac[4]));

        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Dest_gport", (info->dest_gport));
        if (CTC_FLAG_ISSET(info->flags, CTC_IPFIX_DATA_APS_DETECTED))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Aps Dest_group_id", (info->dest_group_id));
        }
        else
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Dest_group_id", (info->dest_group_id));
        }

        tempip = sal_ntohl(info->l3_info.ipv4.ipda);
        sal_inet_ntop(AF_INET, &tempip, buf, CTC_IPV6_ADDR_STR_LEN);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %s\n", "Ipv4_da", buf);

        tempip = sal_ntohl(info->l3_info.ipv4.ipsa);
        sal_inet_ntop(AF_INET, &tempip, buf, CTC_IPV6_ADDR_STR_LEN);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %s\n", "Ipv4_sa", buf);

        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Dscp", ((info->key_type == CTC_IPFIX_KEY_HASH_IPV6)?(info->l3_info.ipv6.dscp):(info->l3_info.ipv4.dscp)));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Ecn", ((info->key_type == CTC_IPFIX_KEY_HASH_IPV6)?(info->l3_info.ipv6.ecn):(info->l3_info.ipv4.ecn)));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Ttl", ((info->key_type == CTC_IPFIX_KEY_HASH_IPV6)?(info->l3_info.ipv6.ttl):(info->l3_info.ipv4.ttl)));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Vrfid", (info->l3_info.vrfid));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Ip fragment", (info->l3_info.ip_frag));

        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Ip packet length", (info->l3_info.ipv4.ip_pkt_len));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Ip identification", (info->l3_info.ipv4.ip_identification));
        ipv6_address[0] = sal_ntohl(info->l3_info.ipv6.ipda[0]);
        ipv6_address[1] = sal_ntohl(info->l3_info.ipv6.ipda[1]);
        ipv6_address[2] = sal_ntohl(info->l3_info.ipv6.ipda[2]);
        ipv6_address[3] = sal_ntohl(info->l3_info.ipv6.ipda[3]);

        sal_inet_ntop(AF_INET6, ipv6_address, buf, CTC_IPV6_ADDR_STR_LEN);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %s\n", "Ipv6_da", buf);

        ipv6_address[0] = sal_ntohl(info->l3_info.ipv6.ipsa[0]);
        ipv6_address[1] = sal_ntohl(info->l3_info.ipv6.ipsa[1]);
        ipv6_address[2] = sal_ntohl(info->l3_info.ipv6.ipsa[2]);
        ipv6_address[3] = sal_ntohl(info->l3_info.ipv6.ipsa[3]);
        sal_inet_ntop(AF_INET6, ipv6_address, buf, CTC_IPV6_ADDR_STR_LEN);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %s\n", "Ipv6_sa", buf);

        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Flow_label", (info->l3_info.ipv6.flow_label));

        if(info->key_type == CTC_IPFIX_KEY_HASH_MPLS || info->key_type == CTC_IPFIX_KEY_HASH_L2_L3 || info->key_type == CTC_IPFIX_KEY_HASH_MPLS_SINGLE)
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Label_num", (info->l3_info.mpls.label_num));
            for (index = 0; index < CTC_IPFIX_LABEL_NUM; index++)
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  Label%d_exp %-5s: 0x%x\n", index, "", (info->l3_info.mpls.label[index].exp));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  Label%d_ttl %-5s: 0x%x\n", index, "", (info->l3_info.mpls.label[index].ttl));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  Label%d_sbit %-4s: 0x%x\n", index, "", (info->l3_info.mpls.label[index].sbit));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  Label%d_label %-3s: 0x%x\n", index, "", (info->l3_info.mpls.label[index].label));
            }
        }
        if (DRV_FROM_AT(lchip))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Arp_op_code", (info->l3_info.arp.op_code));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s:%.4x.%.4x.%.4x \n", "Arp_sender_mac",
                              sal_ntohs(*(unsigned short*)&info->l3_info.arp.sender_mac[0]),  sal_ntohs(*(unsigned short*)&info->l3_info.arp.sender_mac[2]), sal_ntohs(*(unsigned short*)&info->l3_info.arp.sender_mac[4]));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s:%.4x.%.4x.%.4x \n", "Arp_target_mac",
                              sal_ntohs(*(unsigned short*)&info->l3_info.arp.target_mac[0]),  sal_ntohs(*(unsigned short*)&info->l3_info.arp.target_mac[2]), sal_ntohs(*(unsigned short*)&info->l3_info.arp.target_mac[4]));

            tempip = sal_ntohl(info->l3_info.arp.target_ip);
            sal_inet_ntop(AF_INET, &tempip, buf, CTC_IPV6_ADDR_STR_LEN);
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %s\n", "Arp_target_ip", buf);

            tempip = sal_ntohl(info->l3_info.arp.sender_ip);
            sal_inet_ntop(AF_INET, &tempip, buf, CTC_IPV6_ADDR_STR_LEN);
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: %s\n", "Arp_sender_ip", buf);
        }
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "IP_protocol", (info->l4_info.type.ip_protocol));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Aware_tunnel_info_en", (info->l4_info.aware_tunnel_info_en));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Gre_key", (info->l4_info.gre_key));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Vni", (info->l4_info.vni));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Icmpcode", (info->l4_info.icmp.icmpcode));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Icmp_type", (info->l4_info.icmp.icmp_type));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "L4_Source_port", (info->l4_info.l4_port.source_port));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "L4_Dest_port", (info->l4_info.l4_port.dest_port));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Igmp Type", (info->l4_info.igmp.igmp_type));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Tcp Flags(key)", (info->l4_info.tcp_flags));
        if (!DRV_FROM_TMM(lchip))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: %.4x.%.4x.%.4x \n", "Wlan Radio Mac",
                sal_ntohs(*(unsigned short*)&info->l4_info.wlan.radio_mac[0]),  sal_ntohs(*(unsigned short*)&info->l4_info.wlan.radio_mac[2]),
                                                                                sal_ntohs(*(unsigned short*)&info->l4_info.wlan.radio_mac[4]));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Wlan Radio Id", (info->l4_info.wlan.radio_id));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT,"  %-16s: 0x%x\n", "Wlan control packet", (info->l4_info.wlan.is_ctl_pkt));
        }

        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Min Latency", (info->min_latency));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Max Latency", (info->max_latency));
        if (!DRV_FROM_TMM(lchip))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Min Jitter", (info->min_jitter));
        }
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Max Jitter", (info->max_jitter));
        if (DRV_FROM_AT(lchip))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Burst Count", (info->burst_cnt));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Latency Count", (info->latency_cnt));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Hash salt", (info->hash_salt));
        }
        if(DRV_FROM_AT(lchip) && info->flex_key.field_num)
        {
            while(tmp_field_num)
            {
                switch(p_field_list->type)
                {
                    case CTC_FIELD_KEY_SRC_GPORT:
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Source port",p_field_list->data);
                        tmp_field_num--;
                        p_field_list++;
                        break;
                    case CTC_FIELD_KEY_IP_TTL:
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Ip ttl", p_field_list->data);
                        tmp_field_num--;
                        p_field_list++;
                        break;
                    case CTC_FIELD_KEY_DISCARD:
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Discard", p_field_list->data);
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Discard type", p_field_list->mask);
                        tmp_field_num--;
                        p_field_list++;
                        break;
                    case CTC_FIELD_KEY_PRIORITY:
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %-16s: 0x%x\n", "Priority", p_field_list->data);
                        tmp_field_num--;
                        p_field_list++;
                        break;
                    default:
                        break;
                }
            }
        }
        if(DRV_FROM_AT(lchip) && info->xdata.num)
        {
            loop_i = 0;
            while (tmp_xdata_num)
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %s%-5d: 0x%x\n", "Xdata width", loop_i, p_xdata_list->width);
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %s%-4d: 0x%x\n", "Xdata offset", loop_i, p_xdata_list->offset);
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_EXPORT, "  %s%-6d: 0x%x\n", "Xdata data", loop_i, p_xdata_list->data);
                loop_i ++;
                tmp_xdata_num--;
                p_xdata_list++;
            }
        }
        /* delete sw-learning entry form asic, when this entry is aging */
        if(iscpu_set_mode && (CTC_IPFIX_REASON_EXPIRED == info->export_reason))
        {
            (sys_usw_ipfix_delete_entry_by_key(lchip, info));
        }
        info = info->p_next;
    }
    while(info);

    return;
}

int32
sys_usw_ipfix_show_entry_info(ctc_ipfix_data_t* p_info, void* user_data)
{
    uint32 tbl_id = 0;
    uint16 detail = 0;
    ctc_ipfix_traverse_t* p_ipfix_traverse = NULL;
    char key_tbl_name[30] = {0};
    char ad_tbl_name[30] = {0};
    char* key_type[] = {"Mac_key","L2l3_key","Ipv4_key", "Ipv6_key","Mpls_key","UDF_key","UDF_single_key", \
        "Ipv4_single_key", "Ipv6_single_key","Mpls_single_key"};
    char* dir[2] = {"Ingress", "Egress"};
    uint8 lchip = 0;
    uint8 pp_id = 0;
    uint8 tmp_origin_key_type = 0;
    ctc_field_key_t* p_field_list = p_info->flex_key.field_list;
    ctc_field_key_t* tmp_field_list = p_info->flex_key.field_list;
    sys_ipfix_flexed_key_t* p_flexed_key = NULL;
    uint32 loop = 0;
    uint32 tmp_field_num = 0;
    ctc_xdata_field_t* p_xdata_list = p_info->xdata.fields;
    uint32 tmp_xdata_num = p_info->xdata.num;
    if(user_data != NULL)
    {
        p_ipfix_traverse = (ctc_ipfix_traverse_t*)user_data;
        lchip = p_ipfix_traverse->lchip_id;
        if(DRV_FROM_AT(lchip))
        {
            pp_id = lchip - SYS_PP_BASE(lchip);
        }
       
    }

    SYS_IPFIX_INIT_CHECK(lchip);
    detail = p_info->key_index >> 31;
    p_info->key_index = p_info->key_index&0x7fffffff;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "0x%-9x", p_info->key_index);
    if (p_info->key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-18s", key_type[p_info->key_type]);
        tmp_origin_key_type = p_info->key_type;
    }
    else
    {
        p_flexed_key = ctc_vector_get(p_usw_ipfix_master[lchip]->flex_key_vec, (p_info->key_type | (p_info->dir << 7)));
        if (!p_flexed_key)
        {
            return CTC_E_NOT_EXIST;
        }
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-18s", key_type[p_flexed_key->origin_key_type]);
        tmp_origin_key_type = p_flexed_key->origin_key_type;
    }
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "0x%.4x %-1s", p_info->gport, "");
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d", p_info->field_sel_id);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-9d", p_info->max_ttl);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-9d", p_info->min_ttl);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "0x%-9x", p_info->last_timestamp);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-10s", dir[p_info->dir]);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-5d\n", pp_id);

    if (1 == detail)
    {
        tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(tmp_origin_key_type,p_info->dir);
        tbl_id = SYS_IPFIX_GET_TABLE(tbl_id, p_info->dir);
        drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, tbl_id, 0, key_tbl_name);

        tbl_id = (!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))) ? DsIpfixSessionRecord_t : (!p_usw_ipfix_master[lchip]->short_mode ? DsIpfixSessionFullRecord0_t : DsIpfixSessionHalfRecord0_t);
        tbl_id = SYS_IPFIX_GET_TABLE(tbl_id, (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? 0 : p_info->dir);
        drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, tbl_id, 0, ad_tbl_name);

        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Detail Entry Info\n");
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-----------------------------------------------\n");
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :0x%-8x\n", key_tbl_name, p_info->key_index);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :0x%-8x\n", ad_tbl_name, p_info->key_index);

        if (p_info->key_type >= CTC_IPFIX_KEY_HASH_FLEX_BASE)
        {
            for (loop = 0; loop < CTC_FIELD_KEY_NUM; loop++)
            {
                if (!CTC_BMP_ISSET(p_flexed_key->kset.w, loop))
                {
                    continue;
                }
                tmp_field_num++;
                if (p_info->flex_key.field_num > MAX_XKEY_FIELD_NUM)
                {
                    return CTC_E_INVALID_PTR;
                }
                tmp_field_list++;
            }
        }
        if(DRV_FROM_AT(lchip) && p_info->flex_key.field_num)
        {
            tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_info->key_type,p_info->dir);
            tbl_id = SYS_IPFIX_GET_TABLE(tbl_id, p_info->dir);
            drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, tbl_id, 0, key_tbl_name);
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :0x%-8x\n", key_tbl_name, p_info->key_index);

            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "xKey(Value)\n");
            while(tmp_field_num)
            {
                switch(p_field_list->type)
                {
                    case CTC_FIELD_KEY_SRC_GPORT:
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d%-28s:0x%-8x\n",p_field_list->type, "source-port", p_field_list->data);
                        tmp_field_num--;
                        p_field_list++;
                        break;
                    case CTC_FIELD_KEY_IP_TTL:
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d%-28s:0x%-8x\n",p_field_list->type, "ip-ttl", p_field_list->data);
                        tmp_field_num--;
                        p_field_list++;
                        break;
                    case CTC_FIELD_KEY_DISCARD:
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d%-28s:0x%-8x\n",p_field_list->type, "discard", p_field_list->data);
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d%-28s:0x%-8x\n",p_field_list->type, "discard-type", p_field_list->mask);
                        tmp_field_num--;
                        p_field_list++;
                        break;
                    case CTC_FIELD_KEY_PRIORITY:
                        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d%-28s:0x%-8x\n",p_field_list->type, "priority", p_field_list->data);
                        tmp_field_num--;
                        p_field_list++;
                        break;
                    default:
                        break;
                }
            }
        }
        if(DRV_FROM_AT(lchip) && p_info->xdata.num)
        {
            loop = 0;
            while (tmp_xdata_num)
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d%-28s: %u\n", loop, "Xdata width", p_xdata_list->width);
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d%-28s: %u\n", loop,"Xdata offset", p_xdata_list->offset);
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d%-28s: %u\n", loop,"Xdata data", p_xdata_list->data);
                loop ++;
                tmp_xdata_num--;
                p_xdata_list++;
            }
        }
        if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            tbl_id = (!p_usw_ipfix_master[lchip]->short_mode ? DsIpfixSessionFullRecord1_t : DsIpfixSessionHalfRecord1_t);
            drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, tbl_id, 0, ad_tbl_name);
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :0x%-8x\n", ad_tbl_name, p_info->key_index);
        }

    }
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_export_stats(uint8 lchip, uint8 exp_reason, uint64 pkt_cnt, uint64 byte_cnt)
{
    p_usw_ipfix_master[lchip]->exp_cnt_stats[exp_reason-1] ++ ;
    if (exp_reason != CTC_IPFIX_REASON_DUMP )
    {
        p_usw_ipfix_master[lchip]->exp_pkt_cnt_stats[exp_reason - 1] += pkt_cnt;
        p_usw_ipfix_master[lchip]->exp_pkt_byte_stats[exp_reason - 1] += byte_cnt;
    }
    return CTC_E_NONE;
}

#define __DUMP_IPFIX_INFO__

STATIC int32
_sys_usw_ipfix_dump_sample_spool_db(void *node, void* user_date)
{
    sys_traverse_t* p_traverse = (sys_traverse_t*)user_date;
    uint32* p_cnt = (uint32*)p_traverse->data1;
    sal_file_t p_f = (sal_file_t)p_traverse->data;
    ctc_spool_node_t* p_node = (ctc_spool_node_t*)node;
    sys_ipfix_sample_profile_t* p_sample_profile = (sys_ipfix_sample_profile_t*)p_node->data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = p_traverse->value1;
#endif
    if(0xFFFFFFFF == p_node->ref_cnt)
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-24uStatic\n", (*p_cnt), p_sample_profile->ad_index);
    }
    else
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-24u%-20u\n", (*p_cnt), p_sample_profile->ad_index,  p_node->ref_cnt);
    }
    (*p_cnt)++;
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_ipfix_dump_drop_classid_spool_db(void *node, void* user_date)
{
    sys_traverse_t* p_traverse = (sys_traverse_t*)user_date;
    uint32* p_cnt = (uint32*)p_traverse->data1;
    sal_file_t p_f = (sal_file_t)p_traverse->data;
    ctc_spool_node_t* p_node = (ctc_spool_node_t*)node;
    sys_ipfix_drop_classid_t* p_drop_classid = (sys_ipfix_drop_classid_t*)p_node->data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = p_traverse->value1;
#endif
    if(0xFFFFFFFF == p_node->ref_cnt)
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-24uStatic\n", (*p_cnt), p_drop_classid->index.index);
    }
    else
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-24u%-20u\n", (*p_cnt), p_drop_classid->index.index,  p_node->ref_cnt);
    }
    (*p_cnt)++;
    return CTC_E_NONE;
}

int32
_sys_usw_dump_ipfix_flex_key_info(void* node_data, uint32 index,void* user_data)
{
    sys_ipfix_flexed_key_t *ipfix_flex_key = (sys_ipfix_flexed_key_t *)node_data;
    sys_dump_db_traverse_param_t* p_user_data = (sys_dump_db_traverse_param_t*)user_data;
    sal_file_t dump_db_fp = p_user_data->value0;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = p_user_data->lchip;
#endif
    SYS_DUMP_DB_LOG(dump_db_fp, "%-15u%-25u%-15u%-15u%-15u\n", ipfix_flex_key->key_type, 
        ipfix_flex_key->origin_key_type, ipfix_flex_key->dir, ipfix_flex_key->key_size, ipfix_flex_key->mode);
    return CTC_E_NONE;
}

int32
_sys_usw_dump_ipfix_xalu_info(void* node_data,void* user_data)
{
    sys_ipfix_xalu_vec_t *ipfix_xalu = (sys_ipfix_xalu_vec_t *)node_data;
    sys_dump_db_traverse_param_t* p_user_data = (sys_dump_db_traverse_param_t*)user_data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = p_user_data->lchip;
#endif
    sal_file_t dump_db_fp = p_user_data->value0;
    SYS_DUMP_DB_LOG(dump_db_fp, "%-15u%-15u%-15u%-15u%-15u%-15u%-15u%-15u\n", ipfix_xalu->xalu_type[0],ipfix_xalu->xalu_type[1],
        ipfix_xalu->xalu_type[2],ipfix_xalu->xalu_type[3],ipfix_xalu->xalu_type[4],ipfix_xalu->xalu_type[5],ipfix_xalu->xalu_type[6],ipfix_xalu->xalu_type[7]);
    return CTC_E_NONE;
}

int32
sys_usw_ipfix_dump_db(uint8 lchip, sal_file_t p_f, ctc_global_dump_db_t* p_dump_param)
{
    uint8 loop_i = 0;
    sys_traverse_t  param;
    uint32  spool_cnt = 1;

    SYS_IPFIX_LOCK(lchip);
    SYS_DUMP_DB_LOG(p_f, "%s\n", "# IPFIX");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "--------------------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Aging max ptr", p_usw_ipfix_master[lchip]->max_ptr);
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Aging interval", p_usw_ipfix_master[lchip]->aging_interval);
    SYS_DUMP_DB_LOG(p_f, "%-36s: 0x%x\n","Sample index bitmap", p_usw_ipfix_master[lchip]->sip_idx_bmp);
    for(loop_i=0; loop_i<8; loop_i++)
    {
        if(CTC_IS_BIT_SET(p_usw_ipfix_master[lchip]->sip_idx_bmp, loop_i))
        {
            SYS_DUMP_DB_LOG(p_f, "%-16s%-20u: %u\n","Sample interval ", loop_i, p_usw_ipfix_master[lchip]->sip_interval[loop_i]);
        }
    }
    if(p_usw_ipfix_master[lchip]->sample_spool && p_usw_ipfix_master[lchip]->sample_spool->count)
    {
        spool_cnt = 1;
        sal_memset(&param, 0, sizeof(param));
        param.data = (void*)p_f;
        param.data1 = (void*)&spool_cnt;
        param.value1 = lchip;
        SYS_DUMP_DB_LOG(p_f, "Spool type: %s\n","Sample spool");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "IpfixSamplingProfile0/IpfixSamplingProfile1\n");
        SYS_DUMP_DB_LOG(p_f, "%-12s%-24s%-20s\n", "Node","Table index", "Ref count");
        ctc_spool_traverse(p_usw_ipfix_master[lchip]->sample_spool, (spool_traversal_fn)_sys_usw_ipfix_dump_sample_spool_db, (void*)(&param));
    }
    SYS_DUMP_DB_LOG(p_f, "\n");
    if(DRV_FROM_TMM(lchip))
    {
        SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Export interval", p_usw_ipfix_master[lchip]->export_interval);
        SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Short mode", p_usw_ipfix_master[lchip]->short_mode);
        SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Ignore drop reason", p_usw_ipfix_master[lchip]->ignore_drop_reason);
        SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n", "Max Export Entry Num", p_usw_ipfix_master[lchip]->max_export_entry_num);
        for(loop_i=0; loop_i<CTC_BOTH_DIRECTION; loop_i++)
        {
            if(p_usw_ipfix_master[lchip]->drop_classid_spool[loop_i])
            {
                spool_cnt = 1;
                sal_memset(&param, 0, sizeof(param));
                param.data = (void*)p_f;
                param.data1 = (void*)&spool_cnt;
                param.value1 = lchip;
                SYS_DUMP_DB_LOG(p_f, "Spool type: %s\n","drop classid spool");
                SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------------------------------------------------");
                SYS_DUMP_DB_LOG(p_f, "IpfixEngineDiscardMapCtl0/IpfixEngineDiscardMapCtl1\n");
                SYS_DUMP_DB_LOG(p_f, "%-12s%-24s%-20s\n", "Node","Table index", "Ref count");
                ctc_spool_traverse(p_usw_ipfix_master[lchip]->drop_classid_spool[loop_i], (spool_traversal_fn)_sys_usw_ipfix_dump_drop_classid_spool_db, (void*)(&param));
            }
        }
    }
    if(DRV_FROM_AT(lchip))
    {
        /*flex key*/
        sys_dump_db_traverse_param_t user_data;
        user_data.lchip = lchip;
        user_data.value0 = p_f;
        SYS_DUMP_DB_LOG(p_f, "Ipfix flex key\n");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-15s%-25s%-15s%-15s%-15s\n", "Key type", "Origin key type", "Direction", "Key size", "Mode");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------------------------------------------------------");
        ctc_vector_traverse2(p_usw_ipfix_master[lchip]->flex_key_vec, CTC_IPFIX_KEY_HASH_FLEX_BASE, _sys_usw_dump_ipfix_flex_key_info , (void *)&user_data);

        /*xalu*/
        SYS_DUMP_DB_LOG(p_f, "Ipfix xalu\n");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-15s%-15s%-15s%-15s%-15s%-15s%-15s%-15s\n", "Xalu_type0", "Xalu_type1", "Xalu_type2", "Xalu_type3", "Xalu_type4", "Xalu_type5", "Xalu_type6", "Xalu_type7");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------------------------------------------------------------------------------------------");

        ctc_vector_traverse(p_usw_ipfix_master[lchip]->xalu_vec, _sys_usw_dump_ipfix_xalu_info , (void *)&user_data);
    }
    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");
    SYS_IPFIX_UNLOCK(lchip);

    return CTC_E_NONE;
}

#define __SYNC_DMA_INFO__

int32
_sys_usw_ipfix_unmapping_export_reason(uint8 lchip, uint8 sys_reason )
{
    if (sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_EXPIRED))
    {
        return CTC_IPFIX_REASON_EXPIRED;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_TCP_SESSION_CLOSE))
    {
        return CTC_IPFIX_REASON_TCP_CLOSE;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_PACKET_COUNT_OVERFLOW))
    {
        return CTC_IPFIX_REASON_PACKET_CNT_OVERFLOW;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_BYTE_COUNT_OVERFLOW))
    {
        return CTC_IPFIX_REASON_BYTE_CNT_OVERFLOW;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_NEW_FLOW_EXPORT))
    {
        return CTC_IPFIX_REASON_NEW_FLOW_INSERT;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_DESTINATION_CHANGE))
    {
        return CTC_IPFIX_REASON_DEST_CHANGE;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_TS_COUNT_OVERFLOW))
    {
        return CTC_IPFIX_REASON_LAST_TS_OVERFLOW;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_JITTER_OVERFLOW))
    {
        return CTC_IPFIX_REASON_JITTER_OVERFLOW;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_LATENCY_OVERFLOW))
    {
        return CTC_IPFIX_REASON_LATENCY_OVERFLOW;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_TTL_CHANGE))
    {
        return CTC_IPFIX_REASON_TTL_CHANGE;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_DROP_PKT_COUNT_OVERFLOW))
    {
        return CTC_IPFIX_REASON_DROP_CNT_OVERFLOW;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_PACKET_DISCARDTYPE_CHANGE))
    {
        return CTC_IPFIX_REASON_DROP_REASON_CHANGE;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_FLUSH_TIMER_EXPORT))
    {
        return CTC_IPFIX_REASON_DUMP;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_SESSION_PACKET_DROP))
    {
        return CTC_IPFIX_REASON_TC_MARK;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_BURST_EVENT))
    {
        return CTC_IPFIX_REASON_BURST_EVENT;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_LATENCY_EVENT))
    {
        return CTC_IPFIX_REASON_LATENCY_EVENT;
    }
    else if(sys_reason == DRV_CONST(DRV_IPFIX_EXPORTREASON_HASH_CONFLICT_EXPORT))
    {
        return CTC_IPFIX_REASON_HASH_CONFLICT;
    }
    else
    {
        return DRV_CONST(DRV_IPFIX_EXPORTREASON_NO_EXPORT);
    }

}

int32
_sys_usw_ipfix_unmapping_key_type(uint8 lchip, uint8 sys_key_type )
{
    if (DRV_FROM_AT(lchip))
    {
#if defined(ARCTIC)
        return ctc_at_hash_type[sys_key_type];
#endif
    }
    else
    {
        switch (sys_key_type)
        {
            case SYS_IPFIX_HASH_TYPE_L2:
                return CTC_IPFIX_KEY_HASH_MAC;
            case SYS_IPFIX_HASH_TYPE_L2L3:
                return CTC_IPFIX_KEY_HASH_L2_L3;
            case SYS_IPFIX_HASH_TYPE_IPV4:
                /*case SYS_IPFIX_HASH_TYPE_UDF_SHORT:*/
                if (!p_usw_ipfix_master[lchip]->short_mode)
                {
                    return CTC_IPFIX_KEY_HASH_IPV4;
                }
                else
                {
                    return CTC_IPFIX_KEY_HASH_UDF;
                }
            case SYS_IPFIX_HASH_TYPE_IPV6:
                return CTC_IPFIX_KEY_HASH_IPV6;
            case SYS_IPFIX_HASH_TYPE_MPLS:
                return CTC_IPFIX_KEY_HASH_MPLS;
            case SYS_IPFIX_HASH_TYPE_IPV4_SHORT:
                return CTC_IPFIX_KEY_HASH_IPV4;
                /*case SYS_IPFIX_HASH_TYPE_UDF:*/
            case SYS_IPFIX_HASH_TYPE_IPV6_SHORT:
                if (p_usw_ipfix_master[lchip]->short_mode)
                {
                    return CTC_IPFIX_KEY_HASH_IPV6;
                }
                else
                {
                    return CTC_IPFIX_KEY_HASH_UDF;
                }
            default:
                break;
        }
    }
    return 0;
}

int32
_sys_usw_ipfix_mapping_key_type(uint8 lchip, uint8 ctc_key_type )
{
    uint8 key_type = 0;

    if (DRV_FROM_AT(lchip))
    {
#if defined(ARCTIC)
        return sys_at_hash_type[ctc_key_type];
#endif
    }
    else
    {        
        key_type = sys_hash_type[ctc_key_type];
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) &&p_usw_ipfix_master[lchip]->short_mode)
        {
            switch (ctc_key_type)
            {
                case CTC_IPFIX_KEY_HASH_IPV4:
                    return SYS_IPFIX_HASH_TYPE_IPV4_SHORT;
                case CTC_IPFIX_KEY_HASH_IPV6:
                    return SYS_IPFIX_HASH_TYPE_IPV6_SHORT;
                case CTC_IPFIX_KEY_HASH_MPLS:
                    return SYS_IPFIX_HASH_TYPE_IPV4_SHORT;
                case CTC_IPFIX_KEY_HASH_UDF:
                    return SYS_IPFIX_HASH_TYPE_IPV4;
                default:
                    break;
            }
        }
        return key_type;
    }
    return 0;
}

STATIC int32
_sys_usw_ipfix_parser_ad_info(uint8 lchip, ctc_ipfix_data_t* p_user_info, void* p_info)
{
    uint8 dest_chip_id = 0;
    uint32 byte_cnt[2] = {0};
    uint32 dest_type = 0;
    uint32 sub_dest_type = 0;
    uint8 jitter_mode = 0;
    uint8 latency_mode = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);


    dest_type = GetDmaToCpuIpfixAccL2KeyFifo(V, destinationType_f, p_info);

    if (!DRV_IS_DUET2(lchip) && p_user_info->dir == CTC_EGRESS)
    {
        jitter_mode = (dest_type == 4);
        latency_mode = (dest_type == 2);
        dest_type = SYS_IPFIX_UNICAST_DEST;
    }

    if (latency_mode == 1) /* latency*/
    {
        p_user_info->min_latency =  ((GetDmaToCpuIpfixAccL2KeyFifo(V, u1_gMfp_mfpToken_f , p_info) << 8) |
                                     GetDmaToCpuIpfixAccL2KeyFifo(V, minTtl_f , p_info));

        p_user_info->max_latency =  (((GetDmaToCpuIpfixAccL2KeyFifo(V, fragment_f , p_info) &0x1)<< 31) |
                                  ((GetDmaToCpuIpfixAccL2KeyFifo(V, nonFragment_f , p_info)&0x1) << 30) |
                                  ((GetDmaToCpuIpfixAccL2KeyFifo(V, lastTs_f , p_info)&0x3FFFFF) << 8) |
                                   GetDmaToCpuIpfixAccL2KeyFifo(V, maxTtl_f , p_info));
    }
    else
    {
        if (GetDmaToCpuIpfixAccL2KeyFifo(V, fragment_f , p_info))
        {
            p_user_info->flags |= CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED;
        }

        p_user_info->start_timestamp = GetDmaToCpuIpfixAccL2KeyFifo(V, u1_gIpfix_firstTs_f , p_info);
        p_user_info->last_timestamp = DRV_IS_DUET2(lchip) ? GetDmaToCpuIpfixAccL2KeyFifo(V, u1_gIpfix_lastTs_f , p_info):\
            GetDmaToCpuIpfixAccL2KeyFifo(V, lastTs_f , p_info);

        if (jitter_mode == 1)
        {
            p_user_info->max_jitter =  (GetDmaToCpuIpfixAccL2KeyFifo(V, minTtl_f , p_info) << 8 |
                                         GetDmaToCpuIpfixAccL2KeyFifo(V, maxTtl_f , p_info));

            p_user_info->min_jitter = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gL2Mcast_l2McGroupId_f , p_info);
        }
        else
        {
            GetDmaToCpuIpfixAccL2KeyFifo(A, byteCount_f , p_info, byte_cnt);
            p_user_info->byte_count = 0;
            p_user_info->byte_count = byte_cnt[1];
            p_user_info->byte_count <<= 32;
            p_user_info->byte_count |= byte_cnt[0];

            p_user_info->max_ttl = GetDmaToCpuIpfixAccL2KeyFifo(V, maxTtl_f , p_info);
            p_user_info->min_ttl = GetDmaToCpuIpfixAccL2KeyFifo(V, minTtl_f , p_info);
        }
    }

    p_user_info->export_reason = _sys_usw_ipfix_unmapping_export_reason(lchip, GetDmaToCpuIpfixAccL2KeyFifo(V, exportReason_f , p_info));

    p_user_info->tcp_flags = GetDmaToCpuIpfixAccL2KeyFifo(V, tcpFlagsStatus_f , p_info);
    p_user_info->pkt_count = GetDmaToCpuIpfixAccL2KeyFifo(V, packetCount_f , p_info);

    if ((GetDmaToCpuIpfixAccL2KeyFifo(V, u2Type_f, p_info) && GetDmaToCpuIpfixAccL2KeyFifo(V, u2_gAdMode1_droppedPacket_f, p_info)) \
        || GetDmaToCpuIpfixAccL2KeyFifo(V, droppedPacket_f  , p_info))
    {
        p_user_info->flags |= CTC_IPFIX_DATA_DROP_DETECTED;
        if(MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc)
        {
            uint16 drop_reason;
            uint16 discard_type = GetDmaToCpuIpfixAccL2KeyFifo(V, discardType_f, p_info);
            discard_type+=(p_user_info->dir==CTC_EGRESS)?MCHIP_CAP(SYS_CAP_BASE_DISCARD_EPE_START):0;
            MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc(discard_type, &drop_reason);
            p_user_info->drop_reason[0] = drop_reason;
        }
    }

    switch(dest_type)
    {
        case SYS_IPFIX_UNICAST_DEST:
            dest_chip_id = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gUcastToNormal_destChipId_f , p_info);
            p_user_info->dest_gport = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gUcastToNormal_destId_f , p_info);
            p_user_info->dest_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(dest_chip_id, p_user_info->dest_gport);
            break;

        case SYS_IPFIX_L2MC_DEST:
        case SYS_IPFIX_OTHER_MCAST:
            p_user_info->dest_group_id = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gL2Mcast_l2McGroupId_f , p_info);
            p_user_info->flags |= CTC_IPFIX_DATA_L2_MCAST_DETECTED;
            break;
        case SYS_IPFIX_L3MC_DEST:
            p_user_info->dest_group_id = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gL3Mcast_l3McGroupId_f , p_info);
            p_user_info->flags |= CTC_IPFIX_DATA_L3_MCAST_DETECTED;
            break;
        case SYS_IPFIX_BCAST_DEST:
            p_user_info->dest_group_id = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gBcast_floodingId_f, p_info);
            p_user_info->flags |= CTC_IPFIX_DATA_BCAST_DETECTED;
            break;
        case SYS_IPFIX_UNKNOW_PKT_DEST:
            p_user_info->dest_group_id = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gUnknownPkt_floodingId_f, p_info);
            p_user_info->flags |= CTC_IPFIX_DATA_UNKNOW_PKT_DETECTED;
            break;

        case SYS_IPFIX_UNION_DEST:
            sub_dest_type = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gApsGroup_destType_f , p_info);
            switch(sub_dest_type)
            {
                case SYS_IPFIX_SUB_APS_DEST:
                    p_user_info->dest_group_id = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gApsGroup_apsGroupId_f , p_info);
                    p_user_info->flags |= CTC_IPFIX_DATA_APS_DETECTED;
                    break;
                case SYS_IPFIX_SUB_ECMP_DEST:
                    dest_chip_id = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gUcastToNormal_destChipId_f , p_info);
                    p_user_info->dest_gport = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gUcastToNormal_destId_f , p_info);
                    p_user_info->dest_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(dest_chip_id, p_user_info->dest_gport);
                    p_user_info->flags |= CTC_IPFIX_DATA_ECMP_DETECTED;
                    break;
                case SYS_IPFIX_SUB_LINKAGG_DEST:
                    p_user_info->dest_group_id = GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gUcastToLagg_linkaggGroupId_f , p_info);
                    p_user_info->flags |= CTC_IPFIX_DATA_LINKAGG_DETECTED;
                    break;
                case SYS_IPFIX_SUB_CPU_DEST:
                    p_user_info->dest_gport = (1<<CTC_TYPE_PORT_OFFSET|\
                        (GetDmaToCpuIpfixAccL2KeyFifo(V, uDestinationInfo_gUcastToNormal_destChipId_f , p_info)&0x7F)<<CTC_LOCAL_PORT_LENGTH);
                    break;
                default:
                    return CTC_E_INVALID_PARAM;
            }
            break;
        default:
            break;
    }
    if(GetDmaToCpuIpfixAccL2KeyFifo(V, u1Type_f , p_info) && GetDmaToCpuIpfixAccL2KeyFifo(V, u1_gMfp_mfpToken_f , p_info))
    {
        p_user_info->flags |= CTC_IPFIX_DATA_MFP_VALID;
    }

    p_user_info->key_index = GetDmaToCpuIpfixAccL2KeyFifo(V, keyIndex_f, p_info);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "ipfix key index, 0x%x\n", p_user_info->key_index);
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_ipfix_parser_l2_info(uint8 lchip, DmaToCpuIpfixAccL2KeyFifo_m* p_info, ctc_ipfix_data_t* user_info)
{
    uint32 cmd = 0;
    IpfixL2HashFieldSelect_m  hash_field;
    hw_mac_addr_t             mac_sa   = { 0 };
    hw_mac_addr_t             mac_da   = { 0 };
    uint8 use_cvlan = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    user_info->key_type = CTC_IPFIX_KEY_HASH_MAC;
    user_info->field_sel_id = GetDmaToCpuIpfixAccL2KeyFifo(V, flowFieldSel_f,p_info);
    user_info->profile_id = GetDmaToCpuIpfixAccL2KeyFifo(V, ipfixCfgProfileId_f, p_info);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "hash_sel:%d  configure profile id: %d\n",user_info->field_sel_id,
                                    user_info->profile_id);
    CTC_MAX_VALUE_CHECK(user_info->field_sel_id, 15);

    cmd = DRV_IOR(IpfixL2HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, user_info->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    switch(GetIpfixL2HashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            user_info->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            user_info->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDmaToCpuIpfixAccL2KeyFifo(V, globalPort_f, p_info));
            break;
        case 2:
            user_info->logic_port = GetDmaToCpuIpfixAccL2KeyFifo(V, globalPort_f, p_info);
            user_info->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            break;
        case 3:
        case 4:
            user_info->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDmaToCpuIpfixAccL2KeyFifo(V, globalPort_f, p_info));
            user_info->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            break;

        default:
            user_info->port_type = CTC_IPFIX_PORT_TYPE_NONE;
            break;
    }

    use_cvlan = GetDmaToCpuIpfixAccL2KeyFifo(V, flowL2KeyUseCvlan_f, p_info);
    if (use_cvlan)
    {
        user_info->cvlan_prio = GetDmaToCpuIpfixAccL2KeyFifo(V, vtagCos_f, p_info);
        user_info->cvlan = GetDmaToCpuIpfixAccL2KeyFifo(V, vlanId_f, p_info);
        user_info->cvlan_cfi = GetDmaToCpuIpfixAccL2KeyFifo(V, vtagCfi_f, p_info);
        if (GetDmaToCpuIpfixAccL2KeyFifo(V, vlanIdValid_f, p_info))
        {
            user_info->flags |= CTC_IPFIX_DATA_CVLAN_TAGGED;
        }
    }
    else
    {
        user_info->svlan_prio = GetDmaToCpuIpfixAccL2KeyFifo(V, vtagCos_f, p_info);
        user_info->svlan = GetDmaToCpuIpfixAccL2KeyFifo(V, vlanId_f, p_info);
        user_info->svlan_cfi = GetDmaToCpuIpfixAccL2KeyFifo(V, vtagCfi_f, p_info);
        if (GetDmaToCpuIpfixAccL2KeyFifo(V, vlanIdValid_f, p_info))
        {
            user_info->flags |= CTC_IPFIX_DATA_SVLAN_TAGGED;
        }
    }

    user_info->ether_type = GetDmaToCpuIpfixAccL2KeyFifo(V, etherType_f, p_info);
    GetDmaToCpuIpfixAccL2KeyFifo(A, macDa_f, p_info, mac_da);
    if(GetIpfixL2HashFieldSelect(V, macDaUseDstCategoryId_f , &hash_field))
    {
        user_info->dst_cid =  mac_da[0]&0xFF;
        if(mac_da[0] & (1<<8))
        {
            user_info->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    else
    {
        SYS_USW_SET_USER_MAC(user_info->dst_mac, mac_da);
    }

    GetDmaToCpuIpfixAccL2KeyFifo(A, macSa_f, p_info, mac_sa);
    if(GetIpfixL2HashFieldSelect(V, macSaUseSrcCategoryId_f, &hash_field))
    {
        user_info->src_cid = mac_sa[0]&0xFF;
        if(mac_sa[0] & (1<<8))
        {
            user_info->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    else
    {
        SYS_USW_SET_USER_MAC(user_info->src_mac, mac_sa);
    }

    if (GetDmaToCpuIpfixAccL2KeyFifo(V, isEgressKey_f, p_info))
    {
        user_info->dir = CTC_EGRESS;
    }
    else
    {
        user_info->dir = CTC_INGRESS;
    }

    return CTC_E_NONE;

}

STATIC int32
_sys_usw_ipfix_parser_l2l3_info(uint8 lchip, DmaToCpuIpfixAccL2L3KeyFifo_m* p_info, ctc_ipfix_data_t* user_info)
{
    hw_mac_addr_t             mac_sa   = { 0 };
    hw_mac_addr_t             mac_da   = { 0 };
    hw_mac_addr_t             radio_mac = { 0 };
    uint8 use_cvlan = 0;
    uint16 ip_protocol = 0;
    ctc_ipfix_hash_field_sel_t ctc_field_sel;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&ctc_field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    user_info->key_type = CTC_IPFIX_KEY_HASH_L2_L3;
    user_info->field_sel_id = GetDmaToCpuIpfixAccL2L3KeyFifo(V, flowFieldSel_f, p_info);
    user_info->profile_id = GetDmaToCpuIpfixAccL2L3KeyFifo(V, ipfixCfgProfileId_f, p_info);
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, user_info->field_sel_id, CTC_IPFIX_KEY_HASH_L2_L3, &ctc_field_sel));

    if(ctc_field_sel.u.l2_l3.gport)
    {
        user_info->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        user_info->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDmaToCpuIpfixAccL2L3KeyFifo(V, globalPort_f, p_info));
    }
    else if(ctc_field_sel.u.l2_l3.logic_port)
    {
        user_info->logic_port = GetDmaToCpuIpfixAccL2L3KeyFifo(V, globalPort_f, p_info);
        user_info->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
    }
    else if(ctc_field_sel.u.l2_l3.metadata)
    {
        user_info->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDmaToCpuIpfixAccL2L3KeyFifo(V, globalPort_f, p_info));
        user_info->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
    }
    else
    {
        user_info->port_type = CTC_IPFIX_PORT_TYPE_NONE;
    }
    use_cvlan = GetDmaToCpuIpfixAccL2L3KeyFifo(V, flowL2KeyUseCvlan_f,p_info);
    if(use_cvlan)
    {
        if (GetDmaToCpuIpfixAccL2L3KeyFifo(V, vlanIdValid_f , p_info))
        {
            user_info->cvlan = GetDmaToCpuIpfixAccL2L3KeyFifo(V, vlanId_f, p_info);
            user_info->flags |= CTC_IPFIX_DATA_CVLAN_TAGGED;
        }
        user_info->cvlan_prio = GetDmaToCpuIpfixAccL2L3KeyFifo(V, vtagCos_f, p_info);
        user_info->cvlan_cfi = GetDmaToCpuIpfixAccL2L3KeyFifo(V, vtagCfi_f, p_info);
    }
    else
    {
        if (GetDmaToCpuIpfixAccL2L3KeyFifo(V, vlanIdValid_f , p_info))
        {
            user_info->svlan = GetDmaToCpuIpfixAccL2L3KeyFifo(V, vlanId_f, p_info);
            user_info->flags |= CTC_IPFIX_DATA_SVLAN_TAGGED;
        }
        user_info->svlan_prio = GetDmaToCpuIpfixAccL2L3KeyFifo(V, vtagCos_f, p_info);
        user_info->svlan_cfi = GetDmaToCpuIpfixAccL2L3KeyFifo(V, vtagCfi_f, p_info);
    }

    user_info->ether_type = GetDmaToCpuIpfixAccL2L3KeyFifo(V, etherType_f, p_info);
    GetDmaToCpuIpfixAccL2L3KeyFifo(A, macSa_f, p_info, mac_sa);
    GetDmaToCpuIpfixAccL2L3KeyFifo(A, macDa_f, p_info, mac_da);
    SYS_USW_SET_USER_MAC(user_info->src_mac, mac_sa);
    SYS_USW_SET_USER_MAC(user_info->dst_mac, mac_da);

    if (GetDmaToCpuIpfixAccL2L3KeyFifo(V, isEgressKey_f, p_info))
    {
        user_info->dir = CTC_EGRESS;
    }
    else
    {
        user_info->dir = CTC_INGRESS;
    }

    if(ctc_field_sel.u.l2_l3.dst_cid)
    {
        user_info->dst_cid = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_ipDa_f , p_info)&0xFF;
        if(GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_ipDa_f , p_info)&(1<<8))
        {
            user_info->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    else if(ctc_field_sel.u.l2_l3.ip_da)
    {
        user_info->l3_info.ipv4.ipda = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_ipDa_f , p_info);
        user_info->l3_info.ipv4.ipda_masklen = ctc_field_sel.u.l2_l3.ip_da_mask;
    }

    if(ctc_field_sel.u.l2_l3.src_cid)
    {
        user_info->src_cid = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_ipSa_f , p_info)&0xFF;
        if(GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_ipSa_f , p_info)&(1<<8))
        {
            user_info->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    else if(ctc_field_sel.u.l2_l3.ip_sa)
    {
        user_info->l3_info.ipv4.ipsa = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_ipSa_f , p_info);
        user_info->l3_info.ipv4.ipsa_masklen = ctc_field_sel.u.l2_l3.ip_sa_mask;
    }

    if(ctc_field_sel.u.l2_l3.ecn)
    {
        user_info->l3_info.ipv4.ecn = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_ecn_f , p_info);
    }
    if(ctc_field_sel.u.l2_l3.dscp)
    {
        user_info->l3_info.ipv4.dscp = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_dscp_f , p_info);
    }
    if(ctc_field_sel.u.l2_l3.ttl)
    {
        user_info->l3_info.ipv4.ttl = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_ttl_f , p_info);
    }
    if(ctc_field_sel.u.l2_l3.label_num)
    {
        user_info->l3_info.mpls.label_num = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_labelNum_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label0_exp)
    {
        user_info->l3_info.mpls.label[0].exp = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsExp0_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label0_label)
    {
        user_info->l3_info.mpls.label[0].label = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsLabel0_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label0_s)
    {
        user_info->l3_info.mpls.label[0].sbit = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsSbit0_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label0_ttl)
    {
        user_info->l3_info.mpls.label[0].ttl = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsTtl0_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label1_ttl)
    {
        user_info->l3_info.mpls.label[1].exp = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsExp1_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label1_label)
    {
        user_info->l3_info.mpls.label[1].label = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsLabel1_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label1_s)
    {
        user_info->l3_info.mpls.label[1].sbit = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsSbit1_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label1_ttl)
    {
        user_info->l3_info.mpls.label[1].ttl = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsTtl1_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label2_exp)
    {
        user_info->l3_info.mpls.label[2].exp = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsExp2_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label2_label)
    {
        user_info->l3_info.mpls.label[2].label = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsLabel2_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label2_s)
    {
        user_info->l3_info.mpls.label[2].sbit = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsSbit2_f, p_info);
    }
    if(ctc_field_sel.u.l2_l3.mpls_label2_ttl)
    {
        user_info->l3_info.mpls.label[2].ttl = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gMpls_mplsTtl2_f, p_info);
    }

    /* process l4 information */
    user_info->l4_info.aware_tunnel_info_en = GetDmaToCpuIpfixAccL2L3KeyFifo(V, isMergeKey_f, p_info);
    ip_protocol = GetDmaToCpuIpfixAccL2L3KeyFifo(V, layer3HeaderProtocol_f,p_info);

    if ((!ctc_field_sel.u.l2_l3.ip_protocol || (SYS_L4_PROTOCOL_TCP == ip_protocol|| SYS_L4_PROTOCOL_UDP == ip_protocol))&& ctc_field_sel.u.l2_l3.l4_dst_port)
    {
        user_info->l4_info.l4_port.dest_port = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL4_gPort_l4DestPort_f, p_info);
    }
    if ((!ctc_field_sel.u.l2_l3.ip_protocol || (SYS_L4_PROTOCOL_TCP == ip_protocol|| SYS_L4_PROTOCOL_UDP == ip_protocol))&& ctc_field_sel.u.l2_l3.l4_src_port)
    {
        user_info->l4_info.l4_port.source_port = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info);
    }
    if ((!ctc_field_sel.u.l2_l3.ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == ip_protocol) && ctc_field_sel.u.l2_l3.icmp_code)
    {
       user_info->l4_info.icmp.icmpcode = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info)&0xff;
    }
    if ((!ctc_field_sel.u.l2_l3.ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == ip_protocol) && ctc_field_sel.u.l2_l3.icmp_type)
    {
       user_info->l4_info.icmp.icmp_type = (GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info)>>8)&0xff;
    }

    if((!ctc_field_sel.u.l2_l3.ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP == ip_protocol) && ctc_field_sel.u.l2_l3.igmp_type)
    {
        user_info->l4_info.igmp.igmp_type = (GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info)>>8)&0xff;
    }

    if (user_info->l4_info.aware_tunnel_info_en)
    {
        switch(GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_mergeDataType_f, p_info))
        {
            case 1:
                user_info->l4_info.vni = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_mergeData_f, p_info);
                break;
            case 2:
                user_info->l4_info.gre_key = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_mergeData_f, p_info);
                if (ctc_field_sel.u.l2_l3.gre_key)
                {
                    user_info->l4_info.gre_key = user_info->l4_info.gre_key | (GetDmaToCpuIpfixAccL2L3KeyFifo(V, mergeDataExt3_f, p_info) << 24);
                }
                break;
            case 3:
                user_info->l4_info.wlan.radio_id = GetDmaToCpuIpfixAccL2L3KeyFifo(V, mergeDataExt4_f, p_info)&0x1F;
                radio_mac[0] = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL3_gIpv4_mergeData_f,p_info) & 0xFFFFFF;
                radio_mac[0] = radio_mac[0] | ((GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL4_gPort_tcpFlags_f,p_info)&0xFF) << 24);
                radio_mac[1] = GetDmaToCpuIpfixAccL2L3KeyFifo(V, layer3HeaderProtocol_f,p_info)&0xFF;
                radio_mac[1] = radio_mac[1] | ((GetDmaToCpuIpfixAccL2L3KeyFifo(V, mergeDataExt3_f,p_info)&0xFF) << 8);
                SYS_USW_SET_USER_MAC(user_info->l4_info.wlan.radio_mac, radio_mac);
                user_info->l4_info.wlan.is_ctl_pkt = (GetDmaToCpuIpfixAccL2L3KeyFifo(V, mergeDataExt4_f, p_info)>> 5) & 0x01;
                break;
            default:
                break;
        }
    }
    else
    {
        if(ctc_field_sel.u.l2_l3.ip_protocol)
        {
            user_info->l4_info.type.ip_protocol = GetDmaToCpuIpfixAccL2L3KeyFifo(V, layer3HeaderProtocol_f,p_info);
        }
        if(ctc_field_sel.u.l2_l3.gre_key || ctc_field_sel.u.l2_l3.nvgre_key)
        {
            user_info->l4_info.gre_key = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL4_gKey_greKey_f, p_info);
        }
        if (ctc_field_sel.u.l2_l3.vxlan_vni)
        {
            user_info->l4_info.vni = GetDmaToCpuIpfixAccL2L3KeyFifo(V, uL4_gVxlan_vni_f, p_info);
        }
        if (ctc_field_sel.u.l2_l3.tcp_flags)
        {
            user_info->l4_info.tcp_flags =  GetDmaToCpuIpfixAccL2L3KeyFifo(V,uL4_gPort_tcpFlags_f, p_info);
        }
        if (ctc_field_sel.u.l2_l3.ip_frag)
        {
            user_info->l3_info.ip_frag =  SYS_IPFIX_UNMAP_IP_FRAG(GetDmaToCpuIpfixAccL2L3KeyFifo(V,uL3_gIpv4_mergeDataType_f, p_info));
        }
        if (ctc_field_sel.u.l2_l3.ip_identification)
        {
            user_info->l3_info.ipv4.ip_identification =  GetDmaToCpuIpfixAccL2L3KeyFifo(V,uL3_gIpv4_mergeData_f, p_info);
        }
        if (ctc_field_sel.u.l2_l3.vrfid)
        {
            uint16 vrfid =  GetDmaToCpuIpfixAccL2L3KeyFifo(V, mergeDataExt3_f, p_info);
            vrfid |= (GetDmaToCpuIpfixAccL2L3KeyFifo(V, mergeDataExt4_f, p_info)&0x3F << 8);
            user_info->l3_info.vrfid =  vrfid;
        }

    }
    return CTC_E_NONE;

}

STATIC int32
_sys_usw_ipfix_parser_l3_ipv4_info(uint8 lchip, DmaToCpuIpfixAccL3Ipv4KeyFifo_m* p_info, ctc_ipfix_data_t* user_info)
{
    uint32 cmd = 0;
    ctc_ipfix_hash_field_sel_t ctc_field_sel;
    IpfixL3Ipv4HashFieldSelect_m  hash_field;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&ctc_field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    user_info->key_type = CTC_IPFIX_KEY_HASH_IPV4;
    user_info->field_sel_id = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, flowFieldSel_f, p_info);
    user_info->profile_id = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, ipfixCfgProfileId_f, p_info);

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, user_info->field_sel_id, CTC_IPFIX_KEY_HASH_IPV4, &ctc_field_sel));

    if(ctc_field_sel.u.ipv4.gport)
    {
        user_info->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        user_info->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, globalPort_f, p_info));
    }
    else if(ctc_field_sel.u.ipv4.logic_port)
    {
        user_info->logic_port = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, globalPort_f, p_info);
        user_info->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
    }
    else if(ctc_field_sel.u.ipv4.metadata)
    {
        user_info->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, globalPort_f, p_info));
        user_info->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
    }
    else
    {
        user_info->port_type = CTC_IPFIX_PORT_TYPE_NONE;
    }

    if (GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, isEgressKey_f, p_info))
    {
        user_info->dir = CTC_EGRESS;
    }
    else
    {
        user_info->dir = CTC_INGRESS;
    }

    /*ipv4 key*/
    if(ctc_field_sel.u.ipv4.dst_cid)
    {
        user_info->dst_cid = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uIpDa_g2_destCategoryId_f , p_info);
        if(GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uIpDa_g2_destCategoryIdClassfied_f , p_info))
        {
            user_info->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    else
    {
        user_info->l3_info.ipv4.ipda = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uIpDa_g1_ipDa_f , p_info);
        user_info->l3_info.ipv4.ipda_masklen = ctc_field_sel.u.ipv4.ip_da_mask;
    }

    if(ctc_field_sel.u.ipv4.src_cid)
    {
        user_info->src_cid = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uIpSa_g2_srcCategoryId_f , p_info);
        if(GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uIpSa_g2_srcCategoryIdClassfied_f , p_info))
        {
            user_info->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    else
    {
        user_info->l3_info.ipv4.ipsa = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uIpSa_g1_ipSa_f , p_info);
        user_info->l3_info.ipv4.ipsa_masklen = ctc_field_sel.u.ipv4.ip_sa_mask;

    }
    user_info->l3_info.ipv4.ttl = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, ttl_f, p_info);
    user_info->l3_info.ipv4.dscp = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, dscp_f, p_info);
    user_info->l3_info.ipv4.ecn = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, ecn_f, p_info);
    /* process l4 information */
    user_info->l4_info.type.ip_protocol = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, layer3HeaderProtocol_f, p_info);

    if (ctc_field_sel.u.ipv4.vxlan_vni)
    {
        user_info->l4_info.vni = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uL4_gVxlan_vni_f, p_info);
    }
    else if(ctc_field_sel.u.ipv4.gre_key || ctc_field_sel.u.ipv4.nvgre_key)
    {
        user_info->l4_info.gre_key = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uL4_gKey_greKey_f, p_info);
    }
    else if ((!ctc_field_sel.u.ipv4.ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == user_info->l4_info.type.ip_protocol)
        &&(ctc_field_sel.u.ipv4.icmp_code || ctc_field_sel.u.ipv4.icmp_type))
    {
       user_info->l4_info.icmp.icmpcode = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info)&0xff;
       user_info->l4_info.icmp.icmp_type = (GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info)>>8)&0xff;
    }
    else if((!ctc_field_sel.u.ipv4.ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP == user_info->l4_info.type.ip_protocol) && ctc_field_sel.u.ipv4.igmp_type)
    {
        user_info->l4_info.igmp.igmp_type = (GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info)>>8)&0xff;
    }
    else if((!ctc_field_sel.u.ipv4.ip_protocol || (SYS_L4_PROTOCOL_TCP ==user_info->l4_info.type.ip_protocol||SYS_L4_PROTOCOL_UDP==user_info->l4_info.type.ip_protocol)) && (ctc_field_sel.u.ipv4.l4_dst_port || ctc_field_sel.u.ipv4.l4_src_port))
    {
        user_info->l4_info.l4_port.dest_port = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uL4_gPort_l4DestPort_f, p_info);
        user_info->l4_info.l4_port.source_port = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info);
    }

    /*share field*/
    cmd = DRV_IOR(IpfixL3Ipv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, user_info->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    switch(GetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field))
    {
        case 0:
            user_info->l3_info.ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uShareField_g1_fragInfo_f,p_info));
            user_info->l4_info.tcp_flags = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uShareField_g1_tcpFlags_f,p_info);
            break;
        case 1:
            user_info->l3_info.ipv4.ip_identification = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uShareField_g2_ipIdentification_f,p_info);
            break;
        case 2:
            user_info->l3_info.ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uShareField_g3_fragInfo_f,p_info));
            user_info->l3_info.ipv4.ip_pkt_len = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uShareField_g3_ipLength_f,p_info);
            break;
        default:
            user_info->l3_info.ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uShareField_g4_fragInfo_f,p_info));
            user_info->l3_info.vrfid = GetDmaToCpuIpfixAccL3Ipv4KeyFifo(V, uShareField_g4_vrfId_f,p_info);
            break;
    }
    return CTC_E_NONE;

}

STATIC int32
_sys_usw_ipfix_parser_l3_ipv6_info(uint8 lchip, DmaToCpuIpfixAccL3Ipv6KeyFifo_m* p_info, ctc_ipfix_data_t* user_info)
{
    uint32 cmd = 0;
    IpfixL3Ipv6HashFieldSelect_m  hash_field;
    ctc_ipfix_hash_field_sel_t field_sel;  /*used for get ip mask*/
    uint32 ipv6_address[4] = {0, 0, 0, 0};
    uint32 merge_data[2] = {0};

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    user_info->key_type = CTC_IPFIX_KEY_HASH_IPV6;
    user_info->field_sel_id = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, flowFieldSel_f, p_info);
    user_info->profile_id = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, ipfixCfgProfileId_f, p_info);
    cmd = DRV_IOR(IpfixL3Ipv6HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, user_info->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, user_info->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel));

    switch(GetIpfixL3Ipv6HashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            user_info->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            user_info->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, globalPort_f, p_info));
            break;
        case 2:
            user_info->logic_port = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, globalPort_f, p_info);
            user_info->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            break;
        case 3:
        case 4:
            user_info->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, globalPort_f, p_info));
            user_info->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            break;
        default:
            user_info->port_type = CTC_IPFIX_PORT_TYPE_NONE;
            break;
    }

    if (GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, isEgressKey_f, p_info))
    {
        user_info->dir = CTC_EGRESS;
    }
    else
    {
        user_info->dir = CTC_INGRESS;
    }
    user_info->l3_info.ipv6.dscp = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, dscp_f, p_info);

    /* parser l4 info */
    user_info->l4_info.type.ip_protocol = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, layer3HeaderProtocol_f, p_info);
    user_info->l4_info.aware_tunnel_info_en = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, isMergeKey_f, p_info);               

     if ((!field_sel.u.ipv6.ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP == user_info->l4_info.type.ip_protocol)&&(field_sel.u.ipv6.icmp_code || field_sel.u.ipv6.icmp_type))
    {
        user_info->l4_info.icmp.icmpcode = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info)&0xff;
        user_info->l4_info.icmp.icmp_type = (GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info) >> 8)&0xff;
    }
    else if(field_sel.u.ipv6.igmp_type)
    {
        user_info->l4_info.igmp.igmp_type = (GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info) >> 8)&0xff;
    }
    else if((!field_sel.u.ipv6.ip_protocol || (SYS_L4_PROTOCOL_TCP == user_info->l4_info.type.ip_protocol||SYS_L4_PROTOCOL_UDP== user_info->l4_info.type.ip_protocol))
            && (field_sel.u.ipv6.l4_dst_port || field_sel.u.ipv6.l4_src_port))
    {
        user_info->l4_info.l4_port.dest_port = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uL4_gPort_l4DestPort_f, p_info);
        user_info->l4_info.l4_port.source_port = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uL4_gPort_l4SourcePort_f, p_info);
    }
    
    if(!user_info->l4_info.aware_tunnel_info_en)
    {
        if(field_sel.u.ipv6.gre_key || field_sel.u.ipv6.nvgre_key)
        {
            user_info->l4_info.gre_key = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uL4_gKey_greKey_f, p_info);
        }
        else if(field_sel.u.ipv6.vxlan_vni)
        {
            user_info->l4_info.vni = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uL4_gVxlan_vni_f, p_info);
        }
    }

    if(!GetIpfixL3Ipv6HashFieldSelect(V, ipAddressMode_f, &hash_field))
    {
        GetDmaToCpuIpfixAccL3Ipv6KeyFifo(A, uIpSa_g1_ipSa_f , p_info,  ipv6_address);
        user_info->l3_info.ipv6.ipsa[0] = ipv6_address[3];
        user_info->l3_info.ipv6.ipsa[1] = ipv6_address[2];
        user_info->l3_info.ipv6.ipsa[2] = ipv6_address[1];
        user_info->l3_info.ipv6.ipsa[3] = ipv6_address[0];

        GetDmaToCpuIpfixAccL3Ipv6KeyFifo(A, uIpDa_g1_ipDa_f , p_info, ipv6_address);
        user_info->l3_info.ipv6.ipda[0] = ipv6_address[3];
        user_info->l3_info.ipv6.ipda[1] = ipv6_address[2];
        user_info->l3_info.ipv6.ipda[2] = ipv6_address[1];
        user_info->l3_info.ipv6.ipda[3] = ipv6_address[0];

        user_info->l3_info.ipv6.ipda_masklen = field_sel.u.ipv6.ip_da_mask;
        user_info->l3_info.ipv6.ipsa_masklen = field_sel.u.ipv6.ip_sa_mask;
    }
    else
    {
        if(field_sel.u.ipv6.src_cid)
        {
            user_info->src_cid = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_srcCategoryId_f, p_info);
            if(GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_srcCategoryIdClassfied_f, p_info))
            {
                user_info->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
            }
        }
        if(field_sel.u.ipv6.dst_cid)
        {
            user_info->dst_cid = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_destCategoryId_f, p_info);
            if(GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_destCategoryIdClassfied_f, p_info))
            {
                user_info->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
            }
        }
        if(field_sel.u.ipv6.ip_frag)
        {
            user_info->l3_info.ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_fragInfo_f, p_info));
        }
        if(field_sel.u.ipv6.ecn)
        {
            user_info->l3_info.ipv6.ecn = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_ecn_f, p_info);
        }
        if(field_sel.u.ipv6.ttl)
        {
            user_info->l3_info.ipv6.ttl = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_ttl_f, p_info);
        }
        if(field_sel.u.ipv6.flow_label)
        {
            user_info->l3_info.ipv6.flow_label = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_ipv6FlowLabel_f, p_info);
        }
        if(field_sel.u.ipv6.tcp_flags)
        {
            user_info->l4_info.tcp_flags = GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V, uIpSa_g2_tcpFlags_f, p_info);
        }

        if (user_info->l4_info.aware_tunnel_info_en)
        {
            GetDmaToCpuIpfixAccL3Ipv6KeyFifo(A, uIpDa_g2_mergeData_f, p_info,merge_data);
            switch(GetDmaToCpuIpfixAccL3Ipv6KeyFifo(V,uIpDa_g2_mergeDataType_f,p_info))
            {
                case 1:
                    user_info->l4_info.vni = merge_data[0]&0xFFFFFF;
                    break;
                case 2:
                    user_info->l4_info.gre_key = merge_data[0];
                    break;
                case 3:
                    SYS_USW_SET_USER_MAC(user_info->l4_info.wlan.radio_mac, merge_data);
                    user_info->l4_info.wlan.radio_id = (merge_data[1]>>16)&0x1F;
                    user_info->l4_info.wlan.is_ctl_pkt = (merge_data[1]>>21)&0x01;
                    break;
                default:
                    break;
            }
        }
        /*get ipv6 address high bits*/
        GetDmaToCpuIpfixAccL3Ipv6KeyFifo(A, uIpSa_g2_ipSaPrefix_f , p_info,  ipv6_address);
        user_info->l3_info.ipv6.ipsa[0] = ipv6_address[1];
        user_info->l3_info.ipv6.ipsa[1] = ipv6_address[0];

        GetDmaToCpuIpfixAccL3Ipv6KeyFifo(A, uIpDa_g2_ipDaPrefix_f , p_info, ipv6_address);
        user_info->l3_info.ipv6.ipda[0] = ipv6_address[1];
        user_info->l3_info.ipv6.ipda[1] = ipv6_address[0];

        user_info->l3_info.ipv6.ipda_masklen = field_sel.u.ipv6.ip_da_mask;
        user_info->l3_info.ipv6.ipsa_masklen = field_sel.u.ipv6.ip_sa_mask;

    }
    return CTC_E_NONE;

}

STATIC int32
_sys_usw_ipfix_parser_l3_mpls_info(uint8 lchip, DmaToCpuIpfixAccL3MplsKeyFifo_m* p_info, ctc_ipfix_data_t* user_info)
{
    uint32 cmd = 0;
    IpfixL3MplsHashFieldSelect_m  hash_field;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    user_info->key_type = CTC_IPFIX_KEY_HASH_MPLS;
    user_info->field_sel_id = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, flowFieldSel_f, p_info);
    user_info->profile_id = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, ipfixCfgProfileId_f, p_info);

    cmd = DRV_IOR(IpfixL3MplsHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, user_info->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    switch(GetIpfixL3MplsHashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            user_info->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            user_info->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDmaToCpuIpfixAccL3MplsKeyFifo(V, globalPort_f, p_info));
            break;
        case 2:
            user_info->logic_port = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, globalPort_f, p_info);
            user_info->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            break;
        case 3:
        case 4:
            user_info->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDmaToCpuIpfixAccL3MplsKeyFifo(V, globalPort_f, p_info));
            user_info->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            break;
        default:
            user_info->port_type = CTC_IPFIX_PORT_TYPE_NONE;
            break;
    }
    if (GetDmaToCpuIpfixAccL3MplsKeyFifo(V, isEgressKey_f, p_info))
    {
        user_info->dir = CTC_EGRESS;
    }
    else
    {
        user_info->dir = CTC_INGRESS;
    }


    user_info->l3_info.mpls.label_num = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, labelNum_f, p_info);
    if (user_info->l3_info.mpls.label_num > CTC_IPFIX_LABEL_NUM)
    {
        return CTC_E_INVALID_PARAM;
    }

    user_info->l3_info.mpls.label[0].exp = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsExp0_f, p_info);
    user_info->l3_info.mpls.label[0].label = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsLabel0_f, p_info);
    user_info->l3_info.mpls.label[0].sbit = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsSbit0_f, p_info);
    user_info->l3_info.mpls.label[0].ttl = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsTtl0_f, p_info);
    user_info->l3_info.mpls.label[1].exp = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsExp1_f, p_info);
    user_info->l3_info.mpls.label[1].label = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsLabel1_f, p_info);
    user_info->l3_info.mpls.label[1].sbit = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsSbit1_f, p_info);
    user_info->l3_info.mpls.label[1].ttl = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsTtl1_f, p_info);
    user_info->l3_info.mpls.label[2].exp = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsExp2_f, p_info);
    user_info->l3_info.mpls.label[2].label = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsLabel2_f, p_info);
    user_info->l3_info.mpls.label[2].sbit = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsSbit2_f, p_info);
    user_info->l3_info.mpls.label[2].ttl = GetDmaToCpuIpfixAccL3MplsKeyFifo(V, mplsTtl2_f, p_info);
    return CTC_E_NONE;
}

#define __CPU_INTERFACE__
int32
_sys_usw_ipfix_decode_l2_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    uint32 cmd = 0;
    IpfixL2HashFieldSelect_m  hash_field;
    hw_mac_addr_t             mac_sa   = { 0 };
    hw_mac_addr_t             mac_da   = { 0 };

    p_data->field_sel_id = GetDsIpfixL2HashKey(V, flowFieldSel_f , p_key);

    cmd = DRV_IOR(IpfixL2HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_data->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    p_data->dir = GetDsIpfixL2HashKey(V, isEgressKey_f, p_key)?1:0;
    p_data->ether_type = GetDsIpfixL2HashKey(V, etherType_f, p_key);
    p_data->profile_id = GetDsIpfixL2HashKey(V, ipfixCfgProfileId_f, p_key);

    if (GetDsIpfixL2HashKey(V, flowL2KeyUseCvlan_f, p_key))
    {
        p_data->cvlan = GetDsIpfixL2HashKey(V, vlanId_f, p_key);
        p_data->cvlan_cfi = GetDsIpfixL2HashKey(V, vtagCfi_f, p_key);
        p_data->cvlan_prio = GetDsIpfixL2HashKey(V, vtagCos_f, p_key);
        if (GetDsIpfixL2HashKey(V, vlanIdValid_f, p_key))
        {
            p_data->flags |= CTC_IPFIX_DATA_CVLAN_TAGGED;
        }
    }
    else
    {
        p_data->svlan = GetDsIpfixL2HashKey(V, vlanId_f, p_key);
        p_data->svlan_cfi = GetDsIpfixL2HashKey(V, vtagCfi_f, p_key);
        p_data->svlan_prio = GetDsIpfixL2HashKey(V, vtagCos_f, p_key);
        if (GetDsIpfixL2HashKey(V, vlanIdValid_f, p_key))
        {
            p_data->flags |= CTC_IPFIX_DATA_SVLAN_TAGGED;
        }
    }

    switch(GetIpfixL2HashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDsIpfixL2HashKey(V, globalPort_f, p_key));
            break;
        case 2:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            p_data->logic_port = GetDsIpfixL2HashKey(V, globalPort_f, p_key);
            break;
        case 3:
        case 4:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            p_data->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDsIpfixL2HashKey(V, globalPort_f, p_key));
            break;
        default:
            break;
    }

    /* macda macsa dst_cid src_cid */
    GetDsIpfixL2HashKey(A, macDa_f, p_key, mac_da);
    GetDsIpfixL2HashKey(A, macSa_f, p_key, mac_sa);

    if (GetIpfixL2HashFieldSelect(V, macDaUseDstCategoryId_f, &hash_field))
    {
        p_data->dst_cid = mac_da[0]&0xFF;
        if (mac_da[0] & (1 << 8))
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    else
    {
        SYS_USW_SET_USER_MAC(p_data->dst_mac, mac_da);
    }

    if (GetIpfixL2HashFieldSelect(V, macSaUseSrcCategoryId_f, &hash_field))
    {
        p_data->src_cid = mac_sa[0]&0xFF;
        if (mac_sa[0] & (1 << 8))
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    else
    {
        SYS_USW_SET_USER_MAC(p_data->src_mac, mac_sa);
    }
     p_data->fid = GetDsIpfixL2HashKey(V, vsiId_f, p_key); /* TMM ...*/

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_decode_l2l3_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    uint32 cmd = 0;
    IpfixL2L3HashFieldSelect_m  hash_field;
    hw_mac_addr_t             mac_sa   = { 0 };
    hw_mac_addr_t             mac_da   = { 0 };
    hw_mac_addr_t             radio_mac = { 0 };
    ctc_ipfix_l3_info_t* p_l3_info;
    ctc_ipfix_l4_info_t* p_l4_info;
    ctc_ipfix_hash_field_sel_t field_sel;
    uint16 protocol = 0;

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    p_l4_info = (ctc_ipfix_l4_info_t*)&(p_data->l4_info);
    sal_memset(&field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_data->field_sel_id = GetDsIpfixL2L3HashKey(V, flowFieldSel_f , p_key);
    p_data->profile_id = GetDsIpfixL2L3HashKey(V, ipfixCfgProfileId_f , p_key);
    cmd = DRV_IOR(IpfixL2L3HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_data->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    p_data->dir = GetDsIpfixL2L3HashKey(V, isEgressKey_f, p_key)? 1 : 0;
    p_data->ether_type = GetDsIpfixL2L3HashKey(V, etherType_f, p_key);

    if (GetDsIpfixL2L3HashKey(V, flowL2KeyUseCvlan_f, p_key))
    {
        if (GetIpfixL2L3HashFieldSelect(V, vlanIdValidEn_f, &hash_field))
        {
            p_data->cvlan = GetDsIpfixL2L3HashKey(V, vlanId_f, p_key);
            p_data->flags |= CTC_IPFIX_DATA_CVLAN_TAGGED;
        }
        p_data->cvlan_prio = GetDsIpfixL2L3HashKey(V, vtagCos_f, p_key);
        p_data->cvlan_cfi = GetDsIpfixL2L3HashKey(V, vtagCfi_f, p_key);
    }
    else
    {
        if (GetIpfixL2L3HashFieldSelect(V, vlanIdValidEn_f, &hash_field))
        {
            p_data->svlan = GetDsIpfixL2L3HashKey(V, vlanId_f, p_key);
            p_data->flags |= CTC_IPFIX_DATA_SVLAN_TAGGED;
        }
        p_data->svlan_prio = GetDsIpfixL2L3HashKey(V, vtagCos_f, p_key);
        p_data->svlan_cfi = GetDsIpfixL2L3HashKey(V, vtagCfi_f, p_key);

    }

    switch(GetIpfixL2L3HashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDsIpfixL2L3HashKey(V, globalPort_f, p_key));
            break;
        case 2:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            p_data->logic_port = GetDsIpfixL2L3HashKey(V, globalPort_f, p_key);
            break;
        case 3:
        case 4:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            p_data->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDsIpfixL2L3HashKey(V, globalPort_f, p_key));
            break;
        default:
            break;
    }

    GetDsIpfixL2L3HashKey(A, macSa_f, p_key, mac_sa);
    GetDsIpfixL2L3HashKey(A, macDa_f, p_key, mac_da);
    SYS_USW_SET_USER_MAC(p_data->src_mac, mac_sa);
    SYS_USW_SET_USER_MAC(p_data->dst_mac, mac_da);

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_L2_L3, &field_sel));
    /* parser l3 information */
    if (field_sel.u.l2_l3.dst_cid)
    {
        p_data->dst_cid = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipDa_f , p_key)&0xFF;
        if (GetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipDa_f , p_key) & (1 << 8))
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    else
    {
        p_l3_info->ipv4.ipda = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipDa_f , p_key);
        p_l3_info->ipv4.ipda_masklen = field_sel.u.l2_l3.ip_da_mask;
    }
    if (field_sel.u.l2_l3.src_cid)
    {
        p_data->src_cid = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipSa_f , p_key)&0xFF;
        if (GetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipSa_f , p_key) & (1 << 8))
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    else
    {
        p_l3_info->ipv4.ipsa = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipSa_f , p_key);
        p_l3_info->ipv4.ipsa_masklen = field_sel.u.l2_l3.ip_sa_mask;
    }
    if (field_sel.u.l2_l3.ttl)
    {
        p_l3_info->ipv4.ttl = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_ttl_f, p_key);
    }
    if (field_sel.u.l2_l3.dscp)
    {
        p_l3_info->ipv4.dscp = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_dscp_f, p_key);
    }
    if (field_sel.u.l2_l3.ecn)
    {
        p_l3_info->ipv4.ecn = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_ecn_f, p_key);
    }

    if (field_sel.u.l2_l3.label_num)
    {
        p_l3_info->mpls.label_num = GetDsIpfixL2L3HashKey(V, uL3_gMpls_labelNum_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label0_exp)
    {
        p_l3_info->mpls.label[0].exp = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsExp0_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label0_label)
    {
        p_l3_info->mpls.label[0].label = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsLabel0_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label0_s)
    {
        p_l3_info->mpls.label[0].sbit = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsSbit0_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label0_ttl)
    {
        p_l3_info->mpls.label[0].ttl = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsTtl0_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label1_exp)
    {
        p_l3_info->mpls.label[1].exp = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsExp1_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label1_label)
    {
        p_l3_info->mpls.label[1].label = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsLabel1_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label1_s)
    {
        p_l3_info->mpls.label[1].sbit = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsSbit1_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label1_ttl)
    {
        p_l3_info->mpls.label[1].ttl = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsTtl1_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label2_exp)
    {
        p_l3_info->mpls.label[2].exp = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsExp2_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label2_label)
    {
        p_l3_info->mpls.label[2].label = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsLabel2_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label2_s)
    {
        p_l3_info->mpls.label[2].sbit = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsSbit2_f, p_key);
    }
    if(field_sel.u.l2_l3.mpls_label2_ttl)
    {
        p_l3_info->mpls.label[2].ttl = GetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsTtl2_f, p_key);
    }

    /* process l4 information */

    protocol=GetDsIpfixL2L3HashKey(V, layer3HeaderProtocol_f, p_key);
    if ((!field_sel.u.l2_l3.ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == protocol)&&(field_sel.u.l2_l3.icmp_code || field_sel.u.l2_l3.icmp_type))
    {
        p_l4_info->icmp.icmpcode = GetDsIpfixL2L3HashKey(V, uL4_gPort_l4SourcePort_f, p_key)&0xFF;
        p_l4_info->icmp.icmp_type = (GetDsIpfixL2L3HashKey(V, uL4_gPort_l4SourcePort_f, p_key) >> 8)&0xFF;
    }
    else if((!field_sel.u.l2_l3.ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP == protocol) && field_sel.u.l2_l3.igmp_type)
    {
        p_l4_info->igmp.igmp_type = (GetDsIpfixL2L3HashKey(V, uL4_gPort_l4SourcePort_f, p_key) >> 8)&0xFF;
    }
    else if((!field_sel.u.l2_l3.ip_protocol || (SYS_L4_PROTOCOL_TCP ==protocol||SYS_L4_PROTOCOL_UDP== protocol))
            &&(field_sel.u.l2_l3.l4_src_port || field_sel.u.l2_l3.l4_dst_port))
    {
        p_l4_info->l4_port.dest_port = GetDsIpfixL2L3HashKey(V, uL4_gPort_l4DestPort_f, p_key);
        p_l4_info->l4_port.source_port = GetDsIpfixL2L3HashKey(V, uL4_gPort_l4SourcePort_f, p_key);
    }
    p_l4_info->aware_tunnel_info_en = GetDsIpfixL2L3HashKey(V, isMergeKey_f, p_key);

    if (p_l4_info->aware_tunnel_info_en)
    {
        switch (GetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeDataType_f, p_key))
        {
            case 1:
                p_l4_info->vni = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeData_f, p_key);
                break;
            case 2:
                p_l4_info->gre_key = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeData_f, p_key);
                if (field_sel.u.l2_l3.gre_key)
                {
                    p_l4_info->gre_key = (p_l4_info->gre_key | GetDsIpfixL2L3HashKey(V, mergeDataExt3_f, p_key) << 24);
                }
                break;
            case 3:
            case 4:
                p_l4_info->wlan.radio_id = GetDsIpfixL2L3HashKey(V, mergeDataExt4_f, p_key)&0x1F;
                p_l4_info->wlan.is_ctl_pkt = (GetDsIpfixL2L3HashKey(V, mergeDataExt4_f, p_key) >> 5)&0x01;
                radio_mac[0] = GetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeData_f, p_key);
                radio_mac[0] = radio_mac[0] | ((GetDsIpfixL2L3HashKey(V, uL4_gPort_tcpFlags_f, p_key)) << 24);
                radio_mac[1] = GetDsIpfixL2L3HashKey(V, layer3HeaderProtocol_f, p_key);
                radio_mac[1] = radio_mac[1] | ((GetDsIpfixL2L3HashKey(V, mergeDataExt3_f, p_key)) << 8);
                SYS_USW_SET_USER_MAC(p_l4_info->wlan.radio_mac, radio_mac);
                break;
            default:
                break;
        }
    }
    else
    {
        p_l4_info->type.ip_protocol = GetDsIpfixL2L3HashKey(V, layer3HeaderProtocol_f, p_key);
        
        if (field_sel.u.l2_l3.gre_key || field_sel.u.l2_l3.nvgre_key)
        {
            p_l4_info->gre_key = GetDsIpfixL2L3HashKey(V, uL4_gKey_greKey_f, p_key);
        }
        else if (field_sel.u.l2_l3.vxlan_vni)
        {
            p_l4_info->vni = GetDsIpfixL2L3HashKey(V, uL4_gVxlan_vni_f, p_key);
        }

        if (field_sel.u.l2_l3.tcp_flags)
        {
            p_l4_info->tcp_flags = GetDsIpfixL2L3HashKey(V, uL4_gPort_tcpFlags_f , p_key);
        }
        if (field_sel.u.l2_l3.ip_frag)
        {
            p_l3_info->ip_frag =  SYS_IPFIX_UNMAP_IP_FRAG(GetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeDataType_f, p_key));
        }
        if (field_sel.u.l2_l3.ip_identification)
        {
            p_l3_info->ipv4.ip_identification =  GetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeData_f, p_key);
        }
        if (field_sel.u.l2_l3.vrfid)
        {
            uint16 vrfid = 0;
            vrfid =  GetDsIpfixL2L3HashKey(V, mergeDataExt3_f, p_key);
            vrfid |= (GetDsIpfixL2L3HashKey(V, mergeDataExt4_f, p_key)&0x3F << 8);
            p_l3_info->vrfid =  vrfid;
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_decode_ipv4_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    uint32 cmd = 0;
    IpfixL3Ipv4HashFieldSelect_m  hash_field;
    ctc_ipfix_l3_info_t* p_l3_info;
    ctc_ipfix_l4_info_t* p_l4_info;
    ctc_ipfix_hash_field_sel_t field_sel;

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    p_l4_info = (ctc_ipfix_l4_info_t*)&(p_data->l4_info);
    sal_memset(&field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_data->field_sel_id = GetDsIpfixL3Ipv4HashKey(V, flowFieldSel_f, p_key);
    p_data->profile_id = GetDsIpfixL3Ipv4HashKey(V, ipfixCfgProfileId_f, p_key);
    cmd = DRV_IOR(IpfixL3Ipv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_data->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV4, &field_sel));

    p_data->dir = GetDsIpfixL3Ipv4HashKey(V, isEgressKey_f, p_key)?1:0;
    switch(GetIpfixL3Ipv4HashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDsIpfixL3Ipv4HashKey(V, globalPort_f, p_key));
            break;
        case 2:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            p_data->logic_port = GetDsIpfixL3Ipv4HashKey(V, globalPort_f, p_key);
            break;
        case 3:
        case 4:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            p_data->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDsIpfixL3Ipv4HashKey(V, globalPort_f, p_key));
            break;
        default:
            break;
    }
    p_l3_info->ipv4.dscp = GetDsIpfixL3Ipv4HashKey(V, dscp_f , p_key);
    p_l3_info->ipv4.ttl = GetDsIpfixL3Ipv4HashKey(V, ttl_f , p_key);
    p_l3_info->ipv4.ecn = GetDsIpfixL3Ipv4HashKey(V, ecn_f , p_key);

    if (GetIpfixL3Ipv4HashFieldSelect(V, ipDaUseDstCategoryId_f, &hash_field))
    {
        p_data->dst_cid = GetDsIpfixL3Ipv4HashKey(V, destCategoryId_f , p_key);
        if(GetDsIpfixL3Ipv4HashKey(V, destCategoryIdClassfied_f , p_key))
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    if (!GetIpfixL3Ipv4HashFieldSelect(V, ipDaUseDstCategoryId_f, &hash_field))
    {
        p_l3_info->ipv4.ipda = GetDsIpfixL3Ipv4HashKey(V, ipDa_f , p_key);
        p_l3_info->ipv4.ipda_masklen = field_sel.u.ipv4.ip_da_mask;
    }

    if (GetIpfixL3Ipv4HashFieldSelect(V, ipSaUseSrcCategoryId_f, &hash_field))
    {
        p_data->src_cid = GetDsIpfixL3Ipv4HashKey(V, srcCategoryId_f , p_key);
        if(GetDsIpfixL3Ipv4HashKey(V, srcCategoryIdClassfied_f , p_key))
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    if (!(GetIpfixL3Ipv4HashFieldSelect(V, ipSaUseSrcCategoryId_f, &hash_field)))
    {
        p_l3_info->ipv4.ipsa = GetDsIpfixL3Ipv4HashKey(V, ipSa_f , p_key);
        p_l3_info->ipv4.ipsa_masklen = field_sel.u.ipv4.ip_sa_mask;
    } 

    p_l4_info->type.ip_protocol = GetDsIpfixL3Ipv4HashKey(V, layer3HeaderProtocol_f, p_key);
    
    if (field_sel.u.ipv4.vxlan_vni)
    {
      p_l4_info->vni = GetDsIpfixL3Ipv4HashKey(V, uL4_gVxlan_vni_f, p_key);
    }
    else if(field_sel.u.ipv4.gre_key || field_sel.u.ipv4.nvgre_key)
    {
      p_l4_info->gre_key = GetDsIpfixL3Ipv4HashKey(V, uL4_gKey_greKey_f, p_key);
    }
    else if ((!field_sel.u.ipv4.ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == p_l4_info->type.ip_protocol) && (field_sel.u.ipv4.icmp_code || field_sel.u.ipv4.icmp_type))
    {
      p_l4_info->icmp.icmpcode = GetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4SourcePort_f, p_key)&0xff;
      p_l4_info->icmp.icmp_type = (GetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4SourcePort_f, p_key)>>8)&0xff;
    }
    else if((!field_sel.u.ipv4.ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP == p_l4_info->type.ip_protocol)&& field_sel.u.ipv4.igmp_type)
    {
      p_l4_info->igmp.igmp_type = (GetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4SourcePort_f, p_key)>>8)&0xff;
    }
    else if ((!field_sel.u.ipv4.ip_protocol || (SYS_L4_PROTOCOL_TCP == p_l4_info->type.ip_protocol || SYS_L4_PROTOCOL_UDP ==  p_l4_info->type.ip_protocol))
            && (field_sel.u.ipv4.l4_src_port || field_sel.u.ipv4.l4_dst_port))
    {
      p_l4_info->l4_port.dest_port = GetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4DestPort_f, p_key);
      p_l4_info->l4_port.source_port = GetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4SourcePort_f, p_key);
    }

    /*share field*/

    switch (GetIpfixL3Ipv4HashFieldSelect(V, shareFieldMode_f, &hash_field))
    {
        case 0:
            p_l3_info->ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(GetDsIpfixL3Ipv4HashKey(V, uShareField_g1_fragInfo_f, p_key));
            p_l4_info->tcp_flags = GetDsIpfixL3Ipv4HashKey(V, uShareField_g1_tcpFlags_f, p_key);
            break;
        case 1:
            p_l3_info->ipv4.ip_identification = GetDsIpfixL3Ipv4HashKey(V, uShareField_g2_ipIdentification_f, p_key);
            break;
        case 2:
            p_l3_info->ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(GetDsIpfixL3Ipv4HashKey(V, uShareField_g3_fragInfo_f, p_key));
            p_l3_info->ipv4.ip_pkt_len = GetDsIpfixL3Ipv4HashKey(V, uShareField_g3_ipLength_f, p_key);
            break;
        default:
            p_l3_info->ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(GetDmaIpfixAccL3Ipv4KeyFifo(V, uShareField_g4_fragInfo_f, p_key));
            p_l3_info->vrfid = GetDsIpfixL3Ipv4HashKey(V, uShareField_g4_vrfId_f, p_key);
            break;
    }
    p_data->fid = GetDsIpfixL3Ipv4HashKey(V, vsiId_f, p_key); /* TMM ...*/

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_decode_ipv6_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    uint32 cmd = 0;
    IpfixL3Ipv6HashFieldSelect_m  hash_field;
    ctc_ipfix_hash_field_sel_t field_sel;
    uint32 ipv6_address[4] = {0, 0, 0, 0};
    uint32 merge_data[2] = {0};

    sal_memset(&field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_data->field_sel_id = GetDsIpfixL3Ipv6HashKey(V, flowFieldSel_f , p_key);
    p_data->profile_id = GetDsIpfixL3Ipv6HashKey(V, ipfixCfgProfileId_f, p_key);

    cmd = DRV_IOR(IpfixL3Ipv6HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_data->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel));

    p_data->dir = GetDsIpfixL3Ipv6HashKey(V, isEgressKey_f, p_key)?1:0;
    switch(GetIpfixL3Ipv6HashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDsIpfixL3Ipv6HashKey(V, globalPort_f, p_key));
            break;
        case 2:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            p_data->logic_port = GetDsIpfixL3Ipv6HashKey(V, globalPort_f, p_key);
            break;
        case 3:
        case 4:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            p_data->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDsIpfixL3Ipv6HashKey(V, globalPort_f, p_key));
            break;
        default:
            break;
    }
    p_data->l3_info.ipv6.dscp = GetDsIpfixL3Ipv6HashKey(V, dscp_f, p_key);
    p_data->l4_info.type.ip_protocol = GetDsIpfixL3Ipv6HashKey(V, layer3HeaderProtocol_f, p_key);
    p_data->l4_info.aware_tunnel_info_en = GetDsIpfixL3Ipv6HashKey(V, isMergeKey_f, p_key);                 

    if ((!field_sel.u.ipv6.ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP ==  p_data->l4_info.type.ip_protocol )&&(field_sel.u.ipv6.icmp_type || field_sel.u.ipv6.icmp_code))
    {
        p_data->l4_info.icmp.icmpcode = GetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4SourcePort_f, p_key)&0xff;
        p_data->l4_info.icmp.icmp_type = (GetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4SourcePort_f, p_key) >> 8)&0xff;
    }
    else if(field_sel.u.ipv6.igmp_type)
    {
        p_data->l4_info.igmp.igmp_type = (GetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4SourcePort_f, p_key) >> 8)&0xff;
    }
    else if((!field_sel.u.ipv6.ip_protocol || (SYS_L4_PROTOCOL_TCP ==  p_data->l4_info.type.ip_protocol || SYS_L4_PROTOCOL_UDP == p_data->l4_info.type.ip_protocol ) )
            && (field_sel.u.ipv6.l4_src_port || field_sel.u.ipv6.l4_dst_port))
    {
        p_data->l4_info.l4_port.dest_port = GetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4DestPort_f, p_key);
        p_data->l4_info.l4_port.source_port = GetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4SourcePort_f, p_key);
    }
    if(!p_data->l4_info.aware_tunnel_info_en)
    {
        if (field_sel.u.ipv6.gre_key || field_sel.u.ipv6.nvgre_key)
        {
            p_data->l4_info.gre_key = GetDsIpfixL3Ipv6HashKey(V, uL4_gKey_greKey_f, p_key);
        }
        else if (field_sel.u.ipv6.vxlan_vni)
        {
            p_data->l4_info.vni = GetDsIpfixL3Ipv6HashKey(V, uL4_gVxlan_vni_f, p_key);
        }
    }
    if (!GetIpfixL3Ipv6HashFieldSelect(V, ipAddressMode_f, &hash_field))
    {
        GetDsIpfixL3Ipv6HashKey(A, uIpSa_g1_ipSa_f , p_key,  ipv6_address);
        p_data->l3_info.ipv6.ipsa[0] = ipv6_address[3];
        p_data->l3_info.ipv6.ipsa[1] = ipv6_address[2];
        p_data->l3_info.ipv6.ipsa[2] = ipv6_address[1];
        p_data->l3_info.ipv6.ipsa[3] = ipv6_address[0];
        GetDsIpfixL3Ipv6HashKey(A, uIpDa_g1_ipDa_f , p_key, ipv6_address);
        p_data->l3_info.ipv6.ipda[0] = ipv6_address[3];
        p_data->l3_info.ipv6.ipda[1] = ipv6_address[2];
        p_data->l3_info.ipv6.ipda[2] = ipv6_address[1];
        p_data->l3_info.ipv6.ipda[3] = ipv6_address[0];
    }
    else
    {
        if (field_sel.u.ipv6.src_cid)
        {
            p_data->src_cid = GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_srcCategoryId_f, p_key);
            if (GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_srcCategoryIdClassfied_f, p_key))
            {
                p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
            }
        }
        if (field_sel.u.ipv6.dst_cid)
        {
            p_data->dst_cid = GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_destCategoryId_f, p_key);
            if (GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_destCategoryIdClassfied_f, p_key))
            {
                p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
            }
        }
        if (field_sel.u.ipv6.ip_frag)
        {
            p_data->l3_info.ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_fragInfo_f, p_key));
        }
        if (field_sel.u.ipv6.ecn)
        {
            p_data->l3_info.ipv6.ecn = GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_ecn_f, p_key);
        }
        if (field_sel.u.ipv6.ttl)
        {
            p_data->l3_info.ipv6.ttl = GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_ttl_f, p_key);
        }
        if (field_sel.u.ipv6.flow_label)
        {
            p_data->l3_info.ipv6.flow_label = GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_ipv6FlowLabel_f, p_key);
        }
        if (field_sel.u.ipv6.tcp_flags)
        {
            p_data->l4_info.tcp_flags = GetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_tcpFlags_f, p_key);
        }

        if (p_data->l4_info.aware_tunnel_info_en)
        {
            GetDsIpfixL3Ipv6HashKey(A, uIpDa_g2_mergeData_f, p_key, merge_data);
            switch (GetDsIpfixL3Ipv6HashKey(V, uIpDa_g2_mergeDataType_f, p_key))
            {
                case SYS_IPFIX_MERGE_TYPE_VXLAN:
                    p_data->l4_info.vni = merge_data[0]&0xFFFFFF;
                    break;
                case SYS_IPFIX_MERGE_TYPE_GRE:
                    p_data->l4_info.gre_key = merge_data[0];
                    break;
                case SYS_IPFIX_MERGE_TYPE_WLAN:
                    SYS_USW_SET_USER_MAC(p_data->l4_info.wlan.radio_mac, merge_data);
                    p_data->l4_info.wlan.radio_id = (merge_data[1] >> 16)&0x1F;
                    p_data->l4_info.wlan.is_ctl_pkt = (merge_data[1] >> 21)&0x01;
                    break;
                default:
                    break;
            }
        }
        GetDsIpfixL3Ipv6HashKey(A, uIpSa_g2_ipSaPrefix_f , p_key,  ipv6_address);
        p_data->l3_info.ipv6.ipsa[0] = ipv6_address[1];
        p_data->l3_info.ipv6.ipsa[1] = ipv6_address[0];

        GetDsIpfixL3Ipv6HashKey(A, uIpDa_g2_ipDaPrefix_f , p_key, ipv6_address);
        p_data->l3_info.ipv6.ipda[0] = ipv6_address[1];
        p_data->l3_info.ipv6.ipda[1] = ipv6_address[0];


        p_data->l3_info.ipv6.ipda_masklen = field_sel.u.ipv6.ip_da_mask;
        p_data->l3_info.ipv6.ipsa_masklen = field_sel.u.ipv6.ip_sa_mask;

    }

    p_data->l3_info.ipv6.ipda_masklen = field_sel.u.ipv6.ip_da_mask;
    p_data->l3_info.ipv6.ipsa_masklen = field_sel.u.ipv6.ip_sa_mask;
    p_data->fid = GetDsIpfixL3Ipv6HashKey(V, vsiId_f, p_key); /* TMM ...*/
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_decode_mpls_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    uint32 cmd = 0;
    IpfixL3MplsHashFieldSelect_m  hash_field;
    ctc_ipfix_l3_info_t* p_l3_info;

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);

    p_data->dir = GetDsIpfixL3MplsHashKey(V, isEgressKey_f, p_key)?1:0;
    p_data->field_sel_id = GetDsIpfixL3MplsHashKey(V, flowFieldSel_f , p_key);
    p_data->profile_id = GetDsIpfixL3MplsHashKey(V, ipfixCfgProfileId_f, p_key);

    cmd = DRV_IOR(IpfixL3MplsHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_data->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    switch(GetIpfixL3MplsHashFieldSelect(V, globalPortType_f, &hash_field))
    {
        case 1:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
            p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(GetDsIpfixL3MplsHashKey(V, globalPort_f, p_key));
            break;
        case 2:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
            p_data->logic_port = GetDsIpfixL3MplsHashKey(V, globalPort_f, p_key);
            break;
        case 3:
        case 4:
            p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
            p_data->logic_port = SYS_TM_IPFIX_DECODE_METADATA(GetDsIpfixL3MplsHashKey(V, globalPort_f, p_key));
            break;
        default:
            break;
    }

    p_l3_info->mpls.label_num = GetDsIpfixL3MplsHashKey(V, labelNum_f, p_key);
    if (p_l3_info->mpls.label_num > CTC_IPFIX_LABEL_NUM)
    {
        return CTC_E_INVALID_PARAM;
    }

    p_l3_info->mpls.label[0].exp = GetDsIpfixL3MplsHashKey(V, mplsExp0_f, p_key);
    p_l3_info->mpls.label[0].label = GetDsIpfixL3MplsHashKey(V, mplsLabel0_f, p_key);
    p_l3_info->mpls.label[0].sbit = GetDsIpfixL3MplsHashKey(V, mplsSbit0_f, p_key);
    p_l3_info->mpls.label[0].ttl = GetDsIpfixL3MplsHashKey(V, mplsTtl0_f, p_key);
    p_l3_info->mpls.label[1].exp = GetDsIpfixL3MplsHashKey(V, mplsExp1_f, p_key);
    p_l3_info->mpls.label[1].label = GetDsIpfixL3MplsHashKey(V, mplsLabel1_f, p_key);
    p_l3_info->mpls.label[1].sbit = GetDsIpfixL3MplsHashKey(V, mplsSbit1_f, p_key);
    p_l3_info->mpls.label[1].ttl = GetDsIpfixL3MplsHashKey(V, mplsTtl1_f, p_key);
    p_l3_info->mpls.label[2].exp = GetDsIpfixL3MplsHashKey(V, mplsExp2_f, p_key);
    p_l3_info->mpls.label[2].label = GetDsIpfixL3MplsHashKey(V, mplsLabel2_f, p_key);
    p_l3_info->mpls.label[2].sbit = GetDsIpfixL3MplsHashKey(V, mplsSbit2_f, p_key);
    p_l3_info->mpls.label[2].ttl = GetDsIpfixL3MplsHashKey(V, mplsTtl2_f, p_key);
    p_data->fid = GetDsIpfixL3MplsHashKey(V, vsiId_f, p_key); /* TMM ...*/
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_ipfix_decode_ad_info(uint8 lchip, ctc_ipfix_data_t* p_data, DsIpfixSessionRecord_m* p_ad)
{
    uint32 byte_cnt[2] = {0};
    uint32 dest_type = 0;
    uint8 dest_chip= 0;
    uint8 sub_dest_type = 0;
    uint8 jitter_mode = 0;
    uint8 latency_mode = 0;

    dest_type = GetDsIpfixSessionRecord(V, destinationType_f, p_ad);
    if (!DRV_IS_DUET2(lchip) && p_data->dir == CTC_EGRESS)
    {
        jitter_mode = (dest_type == 4);
        latency_mode = (dest_type == 2);
        dest_type = SYS_IPFIX_UNICAST_DEST;
    }

    if (latency_mode == 1) /* latency*/
    {
        p_data->min_latency =  ((GetDsIpfixSessionRecord(V, mfpToken_f , p_ad) << 8) |
                                     GetDsIpfixSessionRecord(V, minTtl_f , p_ad))<<5;

        p_data->max_latency =  (((GetDsIpfixSessionRecord(V, fragment_f , p_ad)&0x1) << 31) |
                                  ((GetDsIpfixSessionRecord(V, nonFragment_f , p_ad)&0x1) << 30) |
                                  ((GetDsIpfixSessionRecord(V, lastTs_f , p_ad)&0x3FFFFF) << 8) |
                                   GetDsIpfixSessionRecord(V, maxTtl_f , p_ad))<<5;
    }
    else
    {
        if (GetDsIpfixSessionRecord(V, fragment_f , p_ad))
        {
            p_data->flags |= CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED;
        }

        p_data->start_timestamp = GetDsIpfixSessionRecord(V, firstTs_f , p_ad);
        p_data->last_timestamp = GetDsIpfixSessionRecord(V, lastTs_f , p_ad);
        if (p_data->last_timestamp < p_data->start_timestamp)
        {
            p_data->last_timestamp |= 0x400000;
        }

        if (jitter_mode == 1)
        {
            p_data->max_jitter =  (GetDsIpfixSessionRecord(V, minTtl_f , p_ad) << 8 |
                                         GetDsIpfixSessionRecord(V, maxTtl_f , p_ad))<<5;

            p_data->min_jitter = GetDsIpfixSessionRecord(V, uDestinationInfo_gL2Mcast_l2McGroupId_f , p_ad)<<5;
        }
        else
        {
            GetDsIpfixSessionRecord(A, byteCount_f , p_ad, byte_cnt);
            p_data->byte_count = 0;
            p_data->byte_count = byte_cnt[1];
            p_data->byte_count <<= 32;
            p_data->byte_count |= byte_cnt[0];

            p_data->max_ttl = GetDsIpfixSessionRecord(V, maxTtl_f , p_ad);
            p_data->min_ttl = GetDsIpfixSessionRecord(V, minTtl_f , p_ad);
        }
    }

    p_data->export_reason = GetDsIpfixSessionRecord(V, exportReason_f , p_ad);
    p_data->tcp_flags = GetDsIpfixSessionRecord(V, tcpFlagsStatus_f , p_ad);
    p_data->pkt_count = GetDsIpfixSessionRecord(V, packetCount_f , p_ad);
    if (GetDsIpfixSessionRecord(V, droppedPacket_f, p_ad))
    {
        p_data->flags |= CTC_IPFIX_DATA_DROP_DETECTED;
        if(MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc)
        {
            uint16 drop_reason;
            uint16 discard_type = GetDsIpfixSessionRecord(V, discardType_f, p_ad);
            discard_type+=(p_data->dir==CTC_EGRESS) ? MCHIP_CAP(SYS_CAP_BASE_DISCARD_EPE_START):0;
            MCHIP_MISC(lchip)->map_drop_reason_sys_to_ctc(discard_type, &drop_reason);
            p_data->drop_reason[0] = drop_reason;
        }
    }

    switch(dest_type)
    {
        case SYS_IPFIX_UNICAST_DEST:
            dest_chip = GetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToNormal_destChipId_f , p_ad);
            p_data->dest_gport = GetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToNormal_destId_f , p_ad);
            p_data->dest_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(dest_chip,  p_data->dest_gport);
            break;
        case SYS_IPFIX_L2MC_DEST:
            p_data->dest_group_id = GetDsIpfixSessionRecord(V, uDestinationInfo_gL2Mcast_l2McGroupId_f , p_ad);
            p_data->flags |= CTC_IPFIX_DATA_L2_MCAST_DETECTED;
            break;
        case SYS_IPFIX_L3MC_DEST:
            p_data->dest_group_id = GetDsIpfixSessionRecord(V, uDestinationInfo_gL3Mcast_l3McGroupId_f , p_ad);
            p_data->flags |= CTC_IPFIX_DATA_L3_MCAST_DETECTED;
            break;
        case SYS_IPFIX_BCAST_DEST:
            p_data->dest_group_id = GetDsIpfixSessionRecord(V, uDestinationInfo_gBcast_floodingId_f, p_ad);
            p_data->flags |= CTC_IPFIX_DATA_BCAST_DETECTED;
            break;
        case SYS_IPFIX_UNKNOW_PKT_DEST:
            p_data->dest_group_id = GetDsIpfixSessionRecord(V, uDestinationInfo_gUnknownPkt_floodingId_f, p_ad);
            p_data->flags |= CTC_IPFIX_DATA_UNKNOW_PKT_DETECTED;
            break;
        case SYS_IPFIX_UNION_DEST:
            sub_dest_type = GetDsIpfixSessionRecord(V, uDestinationInfo_gApsGroup_destType_f , p_ad);
            switch(sub_dest_type)
            {
                case SYS_IPFIX_SUB_APS_DEST:
                    p_data->dest_group_id = GetDsIpfixSessionRecord(V, uDestinationInfo_gApsGroup_apsGroupId_f , p_ad);
                    p_data->flags |= CTC_IPFIX_DATA_APS_DETECTED;
                    break;
                case SYS_IPFIX_SUB_ECMP_DEST:
                    dest_chip = GetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToNormal_destChipId_f , p_ad);
                    p_data->dest_gport = GetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToNormal_destId_f , p_ad);
                    p_data->dest_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(dest_chip, p_data->dest_gport);
                    p_data->flags |= CTC_IPFIX_DATA_ECMP_DETECTED;
                    break;
                case SYS_IPFIX_SUB_LINKAGG_DEST:
                    p_data->dest_group_id = GetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToLagg_linkaggGroupId_f , p_ad);
                    p_data->flags |= CTC_IPFIX_DATA_LINKAGG_DETECTED;
                    break;
                case SYS_IPFIX_SUB_CPU_DEST:
                    p_data->dest_gport = (1<<CTC_TYPE_PORT_OFFSET|\
                        (GetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToNormal_destChipId_f , p_ad)&0x1F)<<CTC_LOCAL_PORT_LENGTH);
                    break;
                default:
                    return CTC_E_INVALID_PARAM;
            }
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }
    if(GetDsIpfixSessionRecord(V, u1Type_f , p_ad) && GetDsIpfixSessionRecord(V, mfpToken_f , p_ad))
    {
        p_data->flags |= CTC_IPFIX_DATA_MFP_VALID;
    }
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_decode_hashkey_ad(uint8 lchip, ctc_ipfix_data_t* p_data, uint8 is_ad, void* p_key)
{
    if (is_ad)
    {
        _sys_usw_ipfix_decode_ad_info(lchip, p_data, (DsIpfixSessionRecord_m*)p_key);
    }
    else
    {
        if (p_usw_ipfix_master[lchip]->callbacks_decode[p_data->key_type])
        {
            CTC_ERROR_RETURN(p_usw_ipfix_master[lchip]->callbacks_decode[p_data->key_type](lchip, p_data, p_key));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_encode_l2_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL2HashKey_m l2_key;
    IpfixL2HashFieldSelect_m  hash_field;
    uint32  mac[2] = {0};
    uint32 cmd = 0;
    uint16 global_port = 0;
    sal_memset(&l2_key, 0, sizeof(l2_key));

    /* process gport, logic-port, metadata */
    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
        SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        SYS_USW_LOGIC_PORT_CHECK(p_key->logic_port);
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        SYS_USW_METADATE_CHECK(p_key->logic_port);
        global_port =  DRV_FROM_TMM(lchip) ? SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port) : SYS_TM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixL2HashKey(V, hashKeyType_f, &l2_key, SYS_IPFIX_HASH_TYPE_L2);
    SetDsIpfixL2HashKey(V, flowFieldSel_f, &l2_key, p_key->field_sel_id);
    SetDsIpfixL2HashKey(V, isEgressKey_f, &l2_key, ((p_key->dir==CTC_EGRESS)?1:0));
    SetDsIpfixL2HashKey(V, etherType_f, &l2_key, p_key->ether_type);
    SetDsIpfixL2HashKey(V, globalPort_f, &l2_key, global_port);
    SetDsIpfixL2HashKey(V, ipfixCfgProfileId_f, &l2_key, p_key->profile_id);
    SetDsIpfixL2HashKey(V, hashKeyType0_f, &l2_key, SYS_IPFIX_HASH_TYPE_L2);
    SetDsIpfixL2HashKey(V, hashKeyType1_f, &l2_key, SYS_IPFIX_HASH_TYPE_L2);

    cmd =DRV_IOR(DRV_FROM_AT(lchip)?IpfixL2HashFieldSelect0_t:IpfixL2HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    if(DRV_FROM_AT(lchip))
    {
         SetDsIpfixL2HashKey(V, ipfixHashSalt_f, &l2_key, p_key->hash_salt);
    }
    if(DRV_FROM_TMM(lchip))
    {
        if(p_key->flags&CTC_IPFIX_DATA_CVLAN_TAGGED)
        {
            SetDsIpfixL2HashKey(V, cvlanId_f, &l2_key, p_key->cvlan);
            SetDsIpfixL2HashKey(V, cvlanIdValid_f, &l2_key, 1);
            SetDsIpfixL2HashKey(V, cvtagCfi_f, &l2_key, p_key->cvlan_cfi);
            SetDsIpfixL2HashKey(V, cvtagCos_f, &l2_key, p_key->cvlan_prio);
        }
        if(p_key->flags&CTC_IPFIX_DATA_SVLAN_TAGGED)
        {
            SetDsIpfixL2HashKey(V, svlanId_f, &l2_key, p_key->svlan);
            SetDsIpfixL2HashKey(V, svlanIdValid_f, &l2_key, 1);
            SetDsIpfixL2HashKey(V, svtagCfi_f, &l2_key, p_key->svlan_cfi);
            SetDsIpfixL2HashKey(V, svtagCos_f, &l2_key, p_key->svlan_prio);
        }
    }
    else
    {
        if((p_key->flags&CTC_IPFIX_DATA_CVLAN_TAGGED) && !(p_key->flags&CTC_IPFIX_DATA_SVLAN_TAGGED))
        {
            SetDsIpfixL2HashKey(V, flowL2KeyUseCvlan_f, &l2_key, 1);
            SetDsIpfixL2HashKey(V, vlanId_f, &l2_key, p_key->cvlan);
            SetDsIpfixL2HashKey(V, vlanIdValid_f, &l2_key, 1);
            SetDsIpfixL2HashKey(V, vtagCfi_f, &l2_key, p_key->cvlan_cfi);
            SetDsIpfixL2HashKey(V, vtagCos_f, &l2_key, p_key->cvlan_prio);
        }
        else if(!(p_key->flags&CTC_IPFIX_DATA_CVLAN_TAGGED) && (p_key->flags&CTC_IPFIX_DATA_SVLAN_TAGGED))
        {
            SetDsIpfixL2HashKey(V, flowL2KeyUseCvlan_f, &l2_key, 0);
            SetDsIpfixL2HashKey(V, vlanId_f, &l2_key, p_key->svlan);
            SetDsIpfixL2HashKey(V, vlanIdValid_f, &l2_key, 1);
            SetDsIpfixL2HashKey(V, vtagCfi_f, &l2_key, p_key->svlan_cfi);
            SetDsIpfixL2HashKey(V, vtagCos_f, &l2_key, p_key->svlan_prio);
        }
        else if((p_key->flags&CTC_IPFIX_DATA_CVLAN_TAGGED) && (p_key->flags&CTC_IPFIX_DATA_SVLAN_TAGGED))
        {
            return CTC_E_PARAM_CONFLICT;
        }
    }
    if(GetIpfixL2HashFieldSelect(V,macDaUseDstCategoryId_f,&hash_field))
    {
        uint8  cid_valid = CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_DST_CID_VALID);
        mac[0] = (cid_valid<<8)| (p_key->dst_cid);
    }
    else
    {
        SYS_USW_SET_HW_MAC(mac, p_key->dst_mac);
    }
    SetDsIpfixL2HashKey(A, macDa_f, &l2_key, mac);
    if(GetIpfixL2HashFieldSelect(V,macSaUseSrcCategoryId_f,&hash_field))
    {
        uint8  cid_valid = CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_SRC_CID_VALID);
        mac[0] = (cid_valid<<8)| (p_key->src_cid);
    }
    else
    {
        SYS_USW_SET_HW_MAC(mac, p_key->src_mac);

    }
    SetDsIpfixL2HashKey(A, macSa_f, &l2_key, mac);

    if(DRV_FROM_TMM(lchip))
    {
         if(p_key->flags&CTC_IPFIX_DATA_SRC_CID_VALID)
         {
            SetDsIpfixL2HashKey(V, srcCategoryIdClassfied_f, &l2_key, 1);
            SetDsIpfixL2HashKey(V, srcCategoryId_f, &l2_key, p_key->src_cid);
         }
         if(p_key->flags&CTC_IPFIX_DATA_DST_CID_VALID)
         {
            SetDsIpfixL2HashKey(V, destCategoryIdClassfied_f, &l2_key, 1);
            SetDsIpfixL2HashKey(V, destCategoryId_f, &l2_key, p_key->dst_cid);
         }
         SetDsIpfixL2HashKey(V, vsiId_f, &l2_key, p_key->fid);
    }
    sal_memcpy((uint8*)p_data, (uint8*)&l2_key, sizeof(l2_key));
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_encode_l2l3_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL2L3HashKey_m l2l3_key;
    IpfixL2L3HashFieldSelect_m  hash_field;
    uint32  mac[2] = {0};
    uint32 cmd = 0;
    uint16 l4_srcport = 0;
    uint16 global_port = 0;
    uint32 cid_field =0;
    uint8 tcp_flag_mask = 0;
    hw_mac_addr_t hw_mac;
    ctc_ipfix_hash_field_sel_t field_sel;

    sal_memset(&l2l3_key, 0, sizeof(l2l3_key));
    sal_memset(&field_sel, 0, sizeof(field_sel));

    
    

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, CTC_IPFIX_KEY_HASH_L2_L3, &field_sel));

    /* process gport, logic-port, metadata */
    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
        SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        SYS_USW_LOGIC_PORT_CHECK(p_key->logic_port);
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        SYS_USW_METADATE_CHECK(p_key->logic_port);
        global_port = DRV_FROM_TMM(lchip) ? SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port) : SYS_TM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixL2L3HashKey(V, hashKeyType0_f, &l2l3_key, SYS_IPFIX_HASH_TYPE_L2L3);
    SetDsIpfixL2L3HashKey(V, hashKeyType1_f, &l2l3_key, SYS_IPFIX_HASH_TYPE_L2L3);
    SetDsIpfixL2L3HashKey(V, flowFieldSel_f, &l2l3_key, p_key->field_sel_id);
    SetDsIpfixL2L3HashKey(V, isEgressKey_f, &l2l3_key, ((p_key->dir==CTC_EGRESS)?1:0));
    SetDsIpfixL2L3HashKey(V, globalPort_f, &l2l3_key, global_port);
    SetDsIpfixL2L3HashKey(V, ipfixCfgProfileId_f, &l2l3_key, p_key->profile_id);
    cmd =DRV_IOR(DRV_FROM_AT(lchip)?IpfixL2L3HashFieldSelect0_t:IpfixL2L3HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    SetDsIpfixL2L3HashKey(V, etherType_f, &l2l3_key, p_key->ether_type);
    SetDsIpfixL2L3HashKey(V, isMergeKey_f, &l2l3_key, p_key->l4_info.aware_tunnel_info_en);
    SetDsIpfixL2L3HashKey(V, isVxlan_f, &l2l3_key, (p_key->l4_info.aware_tunnel_info_en) ? 0 : (!!p_key->l4_info.vni));

    if (DRV_FROM_TMM(lchip))
    {
        SetDsIpfixL2L3HashKey(V, hashKeyType2_f, &l2l3_key, SYS_IPFIX_HASH_TYPE_L2L3);
        SetDsIpfixL2L3HashKey(V, hashKeyType3_f, &l2l3_key, SYS_IPFIX_HASH_TYPE_L2L3);
        SetDsIpfixL2L3HashKey(V, vsiId_f, &l2l3_key, p_key->fid);

        if (p_key->flags&CTC_IPFIX_DATA_CVLAN_TAGGED)
        {
            SetDsIpfixL2L3HashKey(V, cvlanId_f, &l2l3_key, p_key->cvlan);
            SetDsIpfixL2L3HashKey(V, cvlanIdValid_f, &l2l3_key, 1);
            SetDsIpfixL2L3HashKey(V, cvtagCfi_f, &l2l3_key, p_key->cvlan_cfi);
            SetDsIpfixL2L3HashKey(V, cvtagCos_f, &l2l3_key, p_key->cvlan_prio);
        }
        if (p_key->flags&CTC_IPFIX_DATA_SVLAN_TAGGED)
        {
            SetDsIpfixL2L3HashKey(V, svlanId_f, &l2l3_key, p_key->svlan);
            SetDsIpfixL2L3HashKey(V, svlanIdValid_f, &l2l3_key, 1);
            SetDsIpfixL2L3HashKey(V, svtagCfi_f, &l2l3_key, p_key->svlan_cfi);
            SetDsIpfixL2L3HashKey(V, svtagCos_f, &l2l3_key, p_key->svlan_prio);
        }
    }
    else
    {
        if((p_key->flags&CTC_IPFIX_DATA_CVLAN_TAGGED) && !(p_key->flags&CTC_IPFIX_DATA_SVLAN_TAGGED))
        {
            SetDsIpfixL2L3HashKey(V, flowL2KeyUseCvlan_f, &l2l3_key, 1);
            SetDsIpfixL2L3HashKey(V, vlanId_f, &l2l3_key, p_key->cvlan);
            SetDsIpfixL2L3HashKey(V, vlanIdValid_f, &l2l3_key, 1);
            SetDsIpfixL2L3HashKey(V, vtagCfi_f, &l2l3_key, p_key->cvlan_cfi);
            SetDsIpfixL2L3HashKey(V, vtagCos_f, &l2l3_key, p_key->cvlan_prio);
        }
        else if(!(p_key->flags&CTC_IPFIX_DATA_CVLAN_TAGGED) && (p_key->flags&CTC_IPFIX_DATA_SVLAN_TAGGED))
        {
            SetDsIpfixL2L3HashKey(V, flowL2KeyUseCvlan_f, &l2l3_key, 0);
            SetDsIpfixL2L3HashKey(V, vlanId_f, &l2l3_key, p_key->svlan);
            SetDsIpfixL2L3HashKey(V, vlanIdValid_f, &l2l3_key, 1);
            SetDsIpfixL2L3HashKey(V, vtagCfi_f, &l2l3_key, p_key->svlan_cfi);
            SetDsIpfixL2L3HashKey(V, vtagCos_f, &l2l3_key, p_key->svlan_prio);
        }
        else if((p_key->flags&CTC_IPFIX_DATA_CVLAN_TAGGED) && (p_key->flags&CTC_IPFIX_DATA_SVLAN_TAGGED))
        {
            return CTC_E_PARAM_CONFLICT;
        }
    }

    /*encode src_mac and dst_mac */
    if (field_sel.u.l2_l3.mac_sa)
    {
        SYS_USW_SET_HW_MAC(mac, p_key->src_mac);
        SetDsIpfixL2L3HashKey(A, macSa_f, &l2l3_key, mac);
    }
    if (field_sel.u.l2_l3.mac_da)
    {
        SYS_USW_SET_HW_MAC(mac, p_key->dst_mac);
        SetDsIpfixL2L3HashKey(A, macDa_f, &l2l3_key, mac);
    }


    if (DRV_FROM_TMM(lchip))
    {
        if (field_sel.u.l2_l3.dst_cid)
        {
            SetDsIpfixL2L3HashKey(V, destCategoryIdClassfied_f, &l2l3_key, 1);
            SetDsIpfixL2L3HashKey(V, destCategoryId_f, &l2l3_key, p_key->dst_cid);
        }
        if (field_sel.u.l2_l3.src_cid)
        {
            SetDsIpfixL2L3HashKey(V, srcCategoryIdClassfied_f, &l2l3_key, 1);
            SetDsIpfixL2L3HashKey(V, srcCategoryId_f, &l2l3_key, p_key->src_cid);
        }
        if(p_key->l3_info.ipv4.ipda != 0)
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipda_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipda, p_key->l3_info.ipv4.ipda_masklen);
            SetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipDa_f, &l2l3_key, p_key->l3_info.ipv4.ipda);
        }
         if(p_key->l3_info.ipv4.ipsa != 0 )
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipsa_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipsa, p_key->l3_info.ipv4.ipsa_masklen);
            SetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipSa_f, &l2l3_key, p_key->l3_info.ipv4.ipsa);
        }
    }
    else
    {
        if (field_sel.u.l2_l3.dst_cid)
        {
            uint8  cid_valid = CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_DST_CID_VALID);
            cid_field = (cid_valid<<8)|p_key->dst_cid;
            SetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipDa_f, &l2l3_key, cid_field);
        }
        else if(p_key->l3_info.ipv4.ipda != 0)
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipda_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipda, p_key->l3_info.ipv4.ipda_masklen);
            SetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipDa_f, &l2l3_key, p_key->l3_info.ipv4.ipda);
        }
        if (field_sel.u.l2_l3.src_cid)
        {
            uint8  cid_valid = CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_SRC_CID_VALID);
            cid_field = (cid_valid<<8)|p_key->src_cid;
            SetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipSa_f, &l2l3_key, cid_field);
        }
        else if(p_key->l3_info.ipv4.ipsa != 0 )
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipsa_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipsa, p_key->l3_info.ipv4.ipsa_masklen);
            SetDsIpfixL2L3HashKey(V, uL3_gIpv4_ipSa_f, &l2l3_key, p_key->l3_info.ipv4.ipsa);
        }
    }
    if(field_sel.u.l2_l3.ttl)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gIpv4_ttl_f, &l2l3_key, p_key->l3_info.ipv4.ttl);
    }
    if(field_sel.u.l2_l3.dscp)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gIpv4_dscp_f, &l2l3_key, p_key->l3_info.ipv4.dscp);
    }
    if(field_sel.u.l2_l3.ecn)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gIpv4_ecn_f, &l2l3_key, p_key->l3_info.ipv4.ecn);
    }
    if (DRV_FROM_AT(lchip))
    {
        if (p_key->ether_type == ARP_ETHER_TYPE)
        {
            if (field_sel.u.l2_l3.arp_code)
            {
                SetDsIpfixL2L3HashKey(V, uL3_gArp_arpOpCode_f, &l2l3_key, p_key->l3_info.arp.op_code);
            }
            if (field_sel.u.l2_l3.ip_sa )
            {
                SetDsIpfixL2L3HashKey(V, uL3_gArp_senderIp_f, &l2l3_key, p_key->l3_info.arp.sender_ip);
            }
            if (field_sel.u.l2_l3.ip_da )
            {
                SetDsIpfixL2L3HashKey(V, uL3_gArp_targetIp_f, &l2l3_key, p_key->l3_info.arp.target_ip);
            }
            /*encode sender_mac and target_mac */
            if (field_sel.u.l2_l3.arp_mac_sa)
            {
                SYS_USW_SET_HW_MAC(mac, p_key->l3_info.arp.sender_mac);
                SetDsIpfixL2L3HashKey(A, macSa_f, &l2l3_key, mac);
            }
            if (field_sel.u.l2_l3.arp_mac_da)
            {
                SYS_USW_SET_HW_MAC(mac, p_key->l3_info.arp.target_mac);
                SetDsIpfixL2L3HashKey(A, macDa_f, &l2l3_key, mac);
            }
        }
        SetDsIpfixL2L3HashKey(V, ipfixHashSalt_f, &l2l3_key, p_key->hash_salt);
    }
    if(field_sel.u.l2_l3.label_num)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_labelNum_f, &l2l3_key, p_key->l3_info.mpls.label_num);
    }
    if(field_sel.u.l2_l3.mpls_label0_exp)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsExp0_f, &l2l3_key, p_key->l3_info.mpls.label[0].exp);
    }
    if(field_sel.u.l2_l3.mpls_label0_label)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsLabel0_f, &l2l3_key, p_key->l3_info.mpls.label[0].label);
    }
    if(field_sel.u.l2_l3.mpls_label0_s)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsSbit0_f, &l2l3_key, p_key->l3_info.mpls.label[0].sbit);
    }
    if(field_sel.u.l2_l3.mpls_label0_ttl)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsTtl0_f, &l2l3_key, p_key->l3_info.mpls.label[0].ttl);
    }
    if(field_sel.u.l2_l3.mpls_label1_exp)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsExp1_f, &l2l3_key, p_key->l3_info.mpls.label[1].exp);
    }
    if(field_sel.u.l2_l3.mpls_label1_label)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsLabel1_f, &l2l3_key, p_key->l3_info.mpls.label[1].label);
    }
    if(field_sel.u.l2_l3.mpls_label1_s)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsSbit1_f, &l2l3_key, p_key->l3_info.mpls.label[1].sbit);
    }
    if(field_sel.u.l2_l3.mpls_label1_ttl)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsTtl1_f, &l2l3_key, p_key->l3_info.mpls.label[1].ttl);
    }
    if(field_sel.u.l2_l3.mpls_label2_exp)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsExp2_f, &l2l3_key, p_key->l3_info.mpls.label[2].exp);
    }
    if(field_sel.u.l2_l3.mpls_label2_label)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsLabel2_f, &l2l3_key, p_key->l3_info.mpls.label[2].label);
    }
    if(field_sel.u.l2_l3.mpls_label2_s)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsSbit2_f, &l2l3_key, p_key->l3_info.mpls.label[2].sbit);
    }
    if(field_sel.u.l2_l3.mpls_label2_ttl)
    {
        SetDsIpfixL2L3HashKey(V, uL3_gMpls_mplsTtl2_f, &l2l3_key, p_key->l3_info.mpls.label[2].ttl);
    }

    if((!field_sel.u.l2_l3.ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == p_key->l4_info.type.ip_protocol)&&(field_sel.u.l2_l3.icmp_code || field_sel.u.l2_l3.icmp_type))
    {
        l4_srcport = (p_key->l4_info.icmp.icmpcode) & 0xff;
        l4_srcport |=  (((p_key->l4_info.icmp.icmp_type) & 0xff) << 8);
        SetDsIpfixL2L3HashKey(V, uL4_gPort_l4SourcePort_f, &l2l3_key, l4_srcport);
    }
    else if ((!field_sel.u.l2_l3.ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP == p_key->l4_info.type.ip_protocol) && field_sel.u.l2_l3.igmp_type)
    {
        l4_srcport = p_key->l4_info.igmp.igmp_type << 8;
        SetDsIpfixL2L3HashKey(V, uL4_gPort_l4SourcePort_f, &l2l3_key, l4_srcport);
    }
    else if((!field_sel.u.l2_l3.ip_protocol || (SYS_L4_PROTOCOL_TCP ==p_key->l4_info.type.ip_protocol||SYS_L4_PROTOCOL_UDP== p_key->l4_info.type.ip_protocol))
              &&(field_sel.u.l2_l3.l4_src_port || field_sel.u.l2_l3.l4_dst_port))
    {
        SetDsIpfixL2L3HashKey(V, uL4_gPort_l4DestPort_f, &l2l3_key, p_key->l4_info.l4_port.dest_port);
        SetDsIpfixL2L3HashKey(V, uL4_gPort_l4SourcePort_f, &l2l3_key, p_key->l4_info.l4_port.source_port);
    }


    /*gen l4 key*/
    if(field_sel.u.l2_l3.aware_tunnel_info_en)
    {
        if(field_sel.u.l2_l3.vxlan_vni)
        {
            if(DRV_FROM_TMM(lchip))
            {
                SetDsIpfixL2L3HashKey(V, mergeDataType_f, &l2l3_key, 1);
                SetDsIpfixL2L3HashKey(V, mergeData_f, &l2l3_key, p_key->l4_info.vni);
            }
            else
            {
                SetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeDataType_f, &l2l3_key, 1);
                SetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeData_f, &l2l3_key, p_key->l4_info.vni);
            }
        }
        else if(field_sel.u.l2_l3.gre_key || field_sel.u.l2_l3.nvgre_key)
        {
            if(DRV_FROM_TMM(lchip))
            {
                SetDsIpfixL2L3HashKey(V, mergeDataType_f, &l2l3_key, 2);
                SetDsIpfixL2L3HashKey(V, mergeData_f, &l2l3_key, p_key->l4_info.gre_key);
            }
            else
            {
                SetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeDataType_f, &l2l3_key, 2);
                SetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeData_f, &l2l3_key, (p_key->l4_info.gre_key)&0xFFFFFF);
                if (field_sel.u.l2_l3.gre_key)
                {
                    SetDsIpfixL2L3HashKey(V, mergeDataExt3_f, &l2l3_key, (p_key->l4_info.gre_key >> 24)&0xFF);
                }
            }
        }
        else
        {
            uint8 value = 0;
            SetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeDataType_f, &l2l3_key, 3);
            if(field_sel.u.l2_l3.wlan_radio_mac)
            {
                SYS_USW_SET_HW_MAC(hw_mac, p_key->l4_info.wlan.radio_mac);
                SetDsIpfixL2L3HashKey(V, uL3_gIpv4_mergeData_f, &l2l3_key,hw_mac[0]&0xFFFFFF);
                SetDsIpfixL2L3HashKey(V, uL4_gPort_tcpFlags_f, &l2l3_key,(hw_mac[0] >> 24)&0xFF);
                SetDsIpfixL2L3HashKey(V, layer3HeaderProtocol_f, &l2l3_key, hw_mac[1] & 0xFF);
                SetDsIpfixL2L3HashKey(V, mergeDataExt3_f, &l2l3_key, (hw_mac[1]>>8 & 0xFF));
            }
            if(field_sel.u.l2_l3.wlan_radio_id)
            {
                value =  p_key->l4_info.wlan.radio_id;
            }
            if(field_sel.u.l2_l3.wlan_ctl_packet)
            {
                value |= (p_key->l4_info.wlan.is_ctl_pkt<<5);
            }
            SetDsIpfixL2L3HashKey(V, mergeDataExt4_f, &l2l3_key, value);
        }
    }
    else
    {
        if (field_sel.u.l2_l3.gre_key || field_sel.u.l2_l3.nvgre_key)
        {
            SetDsIpfixL2L3HashKey(V, uL4_gKey_greKey_f, &l2l3_key, p_key->l4_info.gre_key);
        }
        else if (field_sel.u.l2_l3.vxlan_vni)
        {
            SetDsIpfixL2L3HashKey(V, uL4_gVxlan_vni_f, &l2l3_key, p_key->l4_info.vni);
        }
    }

    /*From TM.MX, the merge data is not union with the following fields*/
    if(DRV_FROM_TMM(lchip) || !field_sel.u.l2_l3.aware_tunnel_info_en)
    {
        SetDsIpfixL2L3HashKey(V, layer3HeaderProtocol_f, &l2l3_key,p_key->l4_info.type.ip_protocol);
        tcp_flag_mask = GetIpfixL2L3HashFieldSelect(V, g2_tcpFlagsEn_f,&hash_field);
        if(tcp_flag_mask)
        {
            SetDsIpfixL2L3HashKey(V, uL4_gPort_tcpFlags_f, &l2l3_key, (p_key->l4_info.tcp_flags & tcp_flag_mask));
        }

        if (field_sel.u.l2_l3.ip_frag)
        {
            if(DRV_FROM_TMM(lchip))
            {
                SetDsIpfixL2L3HashKey(V,uL3_gIpv4_fragInfo_f, &l2l3_key, SYS_IPFIX_MAP_IP_FRAG(p_key->l3_info.ip_frag));
            }
            else
            {
                SetDsIpfixL2L3HashKey(V,uL3_gIpv4_mergeDataType_f, &l2l3_key, SYS_IPFIX_MAP_IP_FRAG(p_key->l3_info.ip_frag));
            }
        }
        if (field_sel.u.l2_l3.ip_identification)
        {
            if(DRV_FROM_TMM(lchip))
            {
                SetDsIpfixL2L3HashKey(V,uL3_gIpv4_ipIdentification_f, &l2l3_key, p_key->l3_info.ipv4.ip_identification);
            }
            else
            {
                SetDsIpfixL2L3HashKey(V,uL3_gIpv4_mergeData_f, &l2l3_key, p_key->l3_info.ipv4.ip_identification);
            }
        }
        if (field_sel.u.l2_l3.vrfid)
        {
            uint16 vrfid =  p_key->l3_info.vrfid;
            if(DRV_FROM_TMM(lchip))
            {
                SetDsIpfixL2L3HashKey(V, vrfId_f, &l2l3_key, vrfid);
            }
            else
            {
                SetDsIpfixL2L3HashKey(V, mergeDataExt3_f, &l2l3_key, vrfid & 0xFF);
                SetDsIpfixL2L3HashKey(V, mergeDataExt4_f, &l2l3_key, (vrfid>>8 & 0x3F));
            }
        }

    }

    sal_memcpy((uint8*)p_data, (uint8*)&l2l3_key, sizeof(l2l3_key));
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_encode_ipv4_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL3Ipv4HashKey_m ipv4_key;
    IpfixL3Ipv4HashFieldSelect_m hash_field;
    uint16 l4_srcport = 0;
    uint32 cmd = 0;
    uint16 global_port = 0;
    ctc_ipfix_hash_field_sel_t field_sel;
    uint8 tcp_flag_mask = 0;

    sal_memset(&ipv4_key, 0, sizeof(DsIpfixL3Ipv4HashKey_m));
    sal_memset(&hash_field, 0, sizeof(IpfixL3Ipv4HashFieldSelect_m));
    sal_memset(&field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, CTC_IPFIX_KEY_HASH_IPV4, &field_sel));
    /* process gport, logic-port, metadata */
    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
        SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        SYS_USW_LOGIC_PORT_CHECK(p_key->logic_port);
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        SYS_USW_METADATE_CHECK(p_key->logic_port);
        global_port = DRV_FROM_TMM(lchip) ? SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port) : SYS_TM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixL3Ipv4HashKey(V, hashKeyType_f, &ipv4_key, SYS_IPFIX_HASH_TYPE_IPV4);
    SetDsIpfixL3Ipv4HashKey(V, flowFieldSel_f, &ipv4_key, p_key->field_sel_id);
    SetDsIpfixL3Ipv4HashKey(V, isEgressKey_f, &ipv4_key, ((p_key->dir==CTC_EGRESS)?1:0));
    SetDsIpfixL3Ipv4HashKey(V, globalPort_f, &ipv4_key, global_port);

    SetDsIpfixL3Ipv4HashKey(V, hashKeyType0_f, &ipv4_key, SYS_IPFIX_HASH_TYPE_IPV4);
    SetDsIpfixL3Ipv4HashKey(V, hashKeyType1_f, &ipv4_key, SYS_IPFIX_HASH_TYPE_IPV4);

    SetDsIpfixL3Ipv4HashKey(V, ipfixCfgProfileId_f, &ipv4_key, p_key->profile_id);
    cmd =DRV_IOR(DRV_FROM_AT(lchip)?IpfixL3Ipv4HashFieldSelect0_t:IpfixL3Ipv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    SetDsIpfixL3Ipv4HashKey(V, dscp_f, &ipv4_key, p_key->l3_info.ipv4.dscp);
    SetDsIpfixL3Ipv4HashKey(V, ttl_f, &ipv4_key, p_key->l3_info.ipv4.ttl);
    SetDsIpfixL3Ipv4HashKey(V, ecn_f, &ipv4_key, p_key->l3_info.ipv4.ecn);
    SetDsIpfixL3Ipv4HashKey(V, isVxlan_f, &ipv4_key, p_key->l4_info.vni?1:0);
    if(DRV_FROM_AT(lchip))
    {
        SetDsIpfixL3Ipv4HashKey(V, ipfixHashSalt_f, &ipv4_key, p_key->hash_salt);
    }
    /*gen l3 key*/
    if(DRV_FROM_TMM(lchip))
    {
        if(p_key->l3_info.ipv4.ipda != 0)
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipda_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipda, p_key->l3_info.ipv4.ipda_masklen);
            SetDsIpfixL3Ipv4HashKey(V, ipDa_f, &ipv4_key, p_key->l3_info.ipv4.ipda);
        }
        if(p_key->l3_info.ipv4.ipsa != 0 )
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipsa_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipsa, p_key->l3_info.ipv4.ipsa_masklen);
            SetDsIpfixL3Ipv4HashKey(V, ipSa_f, &ipv4_key, p_key->l3_info.ipv4.ipsa);
        }
        if(p_key->flags&CTC_IPFIX_DATA_SRC_CID_VALID)
        {
            SetDsIpfixL3Ipv4HashKey(V, srcCategoryIdClassfied_f, &ipv4_key, 1);
            SetDsIpfixL3Ipv4HashKey(V, srcCategoryId_f, &ipv4_key, p_key->src_cid);
        }
        if(p_key->flags&CTC_IPFIX_DATA_DST_CID_VALID)
        {
           SetDsIpfixL3Ipv4HashKey(V, destCategoryIdClassfied_f, &ipv4_key, 1);
           SetDsIpfixL3Ipv4HashKey(V, destCategoryId_f, &ipv4_key, p_key->dst_cid);
        }
        SetDsIpfixL3Ipv4HashKey(V, vsiId_f, &ipv4_key, p_key->fid);
        tcp_flag_mask = GetIpfixL3Ipv4HashFieldSelect(V, tcpFlagsEn_f, &hash_field);
        SetDsIpfixL3Ipv4HashKey(V, tcpFlags_f, &ipv4_key, (p_key->l4_info.tcp_flags & tcp_flag_mask));
        SetDsIpfixL3Ipv4HashKey(V, fragInfo_f, &ipv4_key, SYS_IPFIX_MAP_IP_FRAG(p_key->l3_info.ip_frag));
    }
    else
    {
        if (GetIpfixL3Ipv4HashFieldSelect(V, ipDaUseDstCategoryId_f,&hash_field))
        {
            SetDsIpfixL3Ipv4HashKey(V, uIpDa_g2_destCategoryId_f, &ipv4_key, p_key->dst_cid);
            SetDsIpfixL3Ipv4HashKey(V, uIpDa_g2_destCategoryIdClassfied_f, &ipv4_key, CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_DST_CID_VALID));
        }
        else if(p_key->l3_info.ipv4.ipda != 0)
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipda_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipda, p_key->l3_info.ipv4.ipda_masklen);
            SetDsIpfixL3Ipv4HashKey(V, uIpDa_g1_ipDa_f, &ipv4_key, p_key->l3_info.ipv4.ipda);
        }
        if (GetIpfixL3Ipv4HashFieldSelect(V, ipSaUseSrcCategoryId_f,&hash_field))
        {
            SetDsIpfixL3Ipv4HashKey(V, uIpSa_g2_srcCategoryId_f, &ipv4_key, p_key->src_cid);
            SetDsIpfixL3Ipv4HashKey(V, uIpSa_g2_srcCategoryIdClassfied_f, &ipv4_key, CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_SRC_CID_VALID));
        }
        else if(p_key->l3_info.ipv4.ipsa != 0 )
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipsa_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipsa, p_key->l3_info.ipv4.ipsa_masklen);
            SetDsIpfixL3Ipv4HashKey(V, uIpSa_g1_ipSa_f, &ipv4_key, p_key->l3_info.ipv4.ipsa);
        }
    }

    /*gen l4 key*/
    SetDsIpfixL3Ipv4HashKey(V, layer3HeaderProtocol_f, &ipv4_key, p_key->l4_info.type.ip_protocol);

   if ((!field_sel.u.ipv4.ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == p_key->l4_info.type.ip_protocol)&&(field_sel.u.ipv4.icmp_code || field_sel.u.ipv4.icmp_type))
    {
        l4_srcport = (p_key->l4_info.icmp.icmpcode) & 0xff;
        l4_srcport |=  (((p_key->l4_info.icmp.icmp_type) & 0xff)<<8);
        SetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4SourcePort_f, &ipv4_key, l4_srcport);
    }
    else if((!field_sel.u.ipv4.ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP ==  p_key->l4_info.type.ip_protocol)&&field_sel.u.ipv4.igmp_type)
    {
        l4_srcport = p_key->l4_info.igmp.igmp_type<<8;
        SetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4SourcePort_f, &ipv4_key, l4_srcport);
    }
    else if (field_sel.u.ipv4.gre_key || field_sel.u.ipv4.nvgre_key)
    {
        SetDsIpfixL3Ipv4HashKey(V, uL4_gKey_greKey_f, &ipv4_key, p_key->l4_info.gre_key);
    }
    else if (field_sel.u.ipv4.vxlan_vni)
    {
        SetDsIpfixL3Ipv4HashKey(V, uL4_gVxlan_vni_f, &ipv4_key, p_key->l4_info.vni);
    }
    else if ((!field_sel.u.ipv4.ip_protocol || (SYS_L4_PROTOCOL_TCP == p_key->l4_info.type.ip_protocol || SYS_L4_PROTOCOL_UDP ==   p_key->l4_info.type.ip_protocol))
            && (field_sel.u.ipv4.l4_src_port || field_sel.u.ipv4.l4_dst_port))
    {
        SetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4DestPort_f, &ipv4_key, p_key->l4_info.l4_port.dest_port);
        SetDsIpfixL3Ipv4HashKey(V, uL4_gPort_l4SourcePort_f, &ipv4_key, p_key->l4_info.l4_port.source_port);
    }

    /*share mode*/
    if(DRV_FROM_TMM(lchip))
    {
        switch(GetIpfixL3Ipv4HashFieldSelect(V,shareFieldMode_f,&hash_field))
        {
            case 0:
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g1_vrfId_f, &ipv4_key, p_key->l3_info.vrfid);
                break;
            case 1:
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g2_ipIdentification_f, &ipv4_key, p_key->l3_info.ipv4.ip_identification);
                break;
            case 2:
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g3_ipLength_f, &ipv4_key, p_key->l3_info.ipv4.ip_pkt_len);
                break;
            default:
                break;
        }
    }
    else
    {
        switch(GetIpfixL3Ipv4HashFieldSelect(V,shareFieldMode_f,&hash_field))
        {
            case 0:
                tcp_flag_mask = GetIpfixL3Ipv4HashFieldSelect(V, u1_g1_tcpFlagsEn_f, &hash_field);
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g1_fragInfo_f, &ipv4_key, SYS_IPFIX_MAP_IP_FRAG(p_key->l3_info.ip_frag));
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g1_tcpFlags_f, &ipv4_key, (p_key->l4_info.tcp_flags & tcp_flag_mask));
                break;
            case 1:
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g2_ipIdentification_f, &ipv4_key, p_key->l3_info.ipv4.ip_identification);
                break;
            case 2:
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g3_fragInfo_f, &ipv4_key, SYS_IPFIX_MAP_IP_FRAG(p_key->l3_info.ip_frag));
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g3_ipLength_f, &ipv4_key, p_key->l3_info.ipv4.ip_pkt_len);
                break;
            default:
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g4_fragInfo_f, &ipv4_key, SYS_IPFIX_MAP_IP_FRAG(p_key->l3_info.ip_frag));
                SetDsIpfixL3Ipv4HashKey(V, uShareField_g4_vrfId_f, &ipv4_key, p_key->l3_info.vrfid);
                break;
        }
    }
    sal_memcpy((uint8*)p_data, (uint8*)&ipv4_key, sizeof(ipv4_key));
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_encode_mpls_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL3MplsHashKey_m mpls_key;
    uint16 global_port = 0;

    sal_memset(&mpls_key, 0, sizeof(mpls_key));

    /* process gport, logic-port, metadata */
    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
        SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        SYS_USW_LOGIC_PORT_CHECK(p_key->logic_port);
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        SYS_USW_METADATE_CHECK(p_key->logic_port);
        global_port = DRV_FROM_TMM(lchip) ? SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port) : SYS_TM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixL3MplsHashKey(V, hashKeyType_f, &mpls_key, SYS_IPFIX_HASH_TYPE_MPLS);
    SetDsIpfixL3MplsHashKey(V, flowFieldSel_f, &mpls_key, p_key->field_sel_id);
    SetDsIpfixL3MplsHashKey(V, isEgressKey_f, &mpls_key, ((p_key->dir==CTC_EGRESS)?1:0));
    SetDsIpfixL3MplsHashKey(V, globalPort_f, &mpls_key, global_port);
    SetDsIpfixL3MplsHashKey(V, ipfixCfgProfileId_f, &mpls_key, p_key->profile_id);

    SetDsIpfixL3MplsHashKey(V, hashKeyType0_f, &mpls_key, SYS_IPFIX_HASH_TYPE_MPLS);
    SetDsIpfixL3MplsHashKey(V, hashKeyType1_f, &mpls_key, SYS_IPFIX_HASH_TYPE_MPLS);
    SetDsIpfixL3MplsHashKey(V, vsiId_f, &mpls_key, p_key->fid);

    /*gen mpls key*/
    SetDsIpfixL3MplsHashKey(V, labelNum_f, &mpls_key, p_key->l3_info.mpls.label_num);

    SetDsIpfixL3MplsHashKey(V, mplsExp0_f, &mpls_key, p_key->l3_info.mpls.label[0].exp);
    SetDsIpfixL3MplsHashKey(V, mplsLabel0_f, &mpls_key, p_key->l3_info.mpls.label[0].label);
    SetDsIpfixL3MplsHashKey(V, mplsSbit0_f, &mpls_key, p_key->l3_info.mpls.label[0].sbit);
    SetDsIpfixL3MplsHashKey(V, mplsTtl0_f, &mpls_key, p_key->l3_info.mpls.label[0].ttl);
    SetDsIpfixL3MplsHashKey(V, mplsExp1_f, &mpls_key, p_key->l3_info.mpls.label[1].exp);
    SetDsIpfixL3MplsHashKey(V, mplsLabel1_f, &mpls_key, p_key->l3_info.mpls.label[1].label);
    SetDsIpfixL3MplsHashKey(V, mplsSbit1_f, &mpls_key, p_key->l3_info.mpls.label[1].sbit);
    SetDsIpfixL3MplsHashKey(V, mplsTtl1_f, &mpls_key, p_key->l3_info.mpls.label[1].ttl);
    SetDsIpfixL3MplsHashKey(V, mplsExp2_f, &mpls_key, p_key->l3_info.mpls.label[2].exp);
    SetDsIpfixL3MplsHashKey(V, mplsLabel2_f, &mpls_key, p_key->l3_info.mpls.label[2].label);
    SetDsIpfixL3MplsHashKey(V, mplsSbit2_f, &mpls_key, p_key->l3_info.mpls.label[2].sbit);
    SetDsIpfixL3MplsHashKey(V, mplsTtl2_f, &mpls_key, p_key->l3_info.mpls.label[2].ttl);
    if(DRV_FROM_AT(lchip))
    {
        SetDsIpfixL3MplsHashKey(V, ipfixHashSalt_f, &mpls_key, p_key->hash_salt);
    }
    sal_memcpy((uint8*)p_data, (uint8*)&mpls_key, sizeof(mpls_key));
    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_encode_ipv6_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL3Ipv6HashKey_m ipv6_key;
    IpfixL3Ipv6HashFieldSelect_m  hash_field;
    uint16 global_port = 0;
    ipv6_addr_t hw_ip6;
    uint16 l4_srcport = 0;
    uint32 cmd = 0;
    uint32 wlan[2] = {0};
    uint32 merge_data[2] = {0};
    uint8 tcp_flag_mask = 0;
    ctc_ipfix_hash_field_sel_t field_sel;

    sal_memset(&ipv6_key, 0, sizeof(ipv6_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));
    sal_memset(&field_sel, 0, sizeof(field_sel));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel));
    /* process gport, logic-port, metadata */
    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
       SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        SYS_USW_LOGIC_PORT_CHECK(p_key->logic_port);
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        SYS_USW_METADATE_CHECK(p_key->logic_port);
        global_port = DRV_FROM_TMM(lchip) ? SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port) : SYS_TM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixL3Ipv6HashKey(V, hashKeyType0_f, &ipv6_key, SYS_IPFIX_HASH_TYPE_IPV6);
    SetDsIpfixL3Ipv6HashKey(V, hashKeyType1_f, &ipv6_key, SYS_IPFIX_HASH_TYPE_IPV6);
    SetDsIpfixL3Ipv6HashKey(V, flowFieldSel_f, &ipv6_key, p_key->field_sel_id);
    SetDsIpfixL3Ipv6HashKey(V, isEgressKey_f, &ipv6_key, ((p_key->dir==CTC_EGRESS)?1:0));
    SetDsIpfixL3Ipv6HashKey(V, globalPort_f, &ipv6_key, global_port);
    SetDsIpfixL3Ipv6HashKey(V, ipfixCfgProfileId_f, &ipv6_key, p_key->profile_id);
    SetDsIpfixL3Ipv6HashKey(V, dscp_f, &ipv6_key, p_key->l3_info.ipv6.dscp);

    SetDsIpfixL3Ipv6HashKey(V, hashKeyType2_f, &ipv6_key, SYS_IPFIX_HASH_TYPE_IPV6);
    SetDsIpfixL3Ipv6HashKey(V, hashKeyType3_f, &ipv6_key, SYS_IPFIX_HASH_TYPE_IPV6);
    SetDsIpfixL3Ipv6HashKey(V, vsiId_f, &ipv6_key, p_key->fid);

    cmd =DRV_IOR(DRV_FROM_AT(lchip)?IpfixL3Ipv6HashFieldSelect0_t:IpfixL3Ipv6HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    SetDsIpfixL3Ipv6HashKey(V, isMergeKey_f, &ipv6_key, p_key->l4_info.aware_tunnel_info_en);
    SetDsIpfixL3Ipv6HashKey(V, isVxlan_f, &ipv6_key, (p_key->l4_info.aware_tunnel_info_en) ? 0 : (!!p_key->l4_info.vni));
    SetDsIpfixL3Ipv6HashKey(V, layer3HeaderProtocol_f, &ipv6_key, p_key->l4_info.type.ip_protocol);

    if ((!field_sel.u.ipv6.ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP ==  p_key->l4_info.type.ip_protocol )&&(field_sel.u.ipv6.icmp_type || field_sel.u.ipv6.icmp_code))
    {
        l4_srcport = (p_key->l4_info.icmp.icmpcode) & 0xff;
        l4_srcport |= (((p_key->l4_info.icmp.icmp_type) & 0xff) << 8);
        SetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4SourcePort_f, &ipv6_key, l4_srcport);
    }
    else if(field_sel.u.ipv6.igmp_type)
    {
        SetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4SourcePort_f, &ipv6_key, (p_key->l4_info.igmp.igmp_type << 8));
    }
    else if((!field_sel.u.ipv6.ip_protocol || (SYS_L4_PROTOCOL_TCP ==  p_key->l4_info.type.ip_protocol || SYS_L4_PROTOCOL_UDP == p_key->l4_info.type.ip_protocol ) )
               && (field_sel.u.ipv6.l4_src_port || field_sel.u.ipv6.l4_dst_port))
    {
        SetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4DestPort_f, &ipv6_key, p_key->l4_info.l4_port.dest_port);
        SetDsIpfixL3Ipv6HashKey(V, uL4_gPort_l4SourcePort_f, &ipv6_key, p_key->l4_info.l4_port.source_port);
    }

    if(!p_key->l4_info.aware_tunnel_info_en)
    {
        if (field_sel.u.ipv6.gre_key || field_sel.u.ipv6.nvgre_key)
        {
            SetDsIpfixL3Ipv6HashKey(V, uL4_gKey_greKey_f, &ipv6_key, p_key->l4_info.gre_key);
        }
        else if(field_sel.u.ipv6.vxlan_vni)
        {
            SetDsIpfixL3Ipv6HashKey(V, uL4_gVxlan_vni_f, &ipv6_key, p_key->l4_info.vni);
        }
    }
    if(DRV_FROM_AT(lchip))
    {
        SetDsIpfixL3Ipv6HashKey(V, ipfixHashSalt_f, &ipv6_key, p_key->hash_salt);
        if(field_sel.u.ipv6.vrfid)
        {
            SetDsIpfixL3Ipv6HashKey(V, vrfId_f, &ipv6_key,  p_key->l3_info.vrfid);
        }
    }

    if(DRV_FROM_TMM(lchip))
    {
        IPFIX_IPV6_MASK_LEN_CHECK(p_key->l3_info.ipv6.ipsa_masklen);
        IPFIX_IPV6_MASK_LEN_CHECK(p_key->l3_info.ipv6.ipda_masklen);

        IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipsa, p_key->l3_info.ipv6.ipsa_masklen);
        IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipda, p_key->l3_info.ipv6.ipda_masklen);

        IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipda);
        SetDsIpfixL3Ipv6HashKey(A, ipDa_f, &ipv6_key, hw_ip6);

        IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipsa);
        SetDsIpfixL3Ipv6HashKey(A, ipSa_f, &ipv6_key, hw_ip6);

        if(p_key->l4_info.aware_tunnel_info_en)
        {
            SetDsIpfixL3Ipv6HashKey(V, isMergeKey_f, &ipv6_key, 1);
            if(field_sel.u.ipv6.vxlan_vni)
            {
                SetDsIpfixL3Ipv6HashKey(V, mergeDataType_f, &ipv6_key,SYS_IPFIX_MERGE_TYPE_VXLAN);
                merge_data[0] = p_key->l4_info.vni;
                SetDsIpfixL3Ipv6HashKey(A, mergeData_f, &ipv6_key, merge_data);
            }
            else if(field_sel.u.ipv6.gre_key || field_sel.u.ipv6.nvgre_key)
            {
                SetDsIpfixL3Ipv6HashKey(V, mergeDataType_f, &ipv6_key,SYS_IPFIX_MERGE_TYPE_GRE);
                merge_data[0] = p_key->l4_info.gre_key;
                SetDsIpfixL3Ipv6HashKey(A, mergeData_f, &ipv6_key, merge_data);
            }
        }
        if(field_sel.u.ipv6.src_cid)
        {
            SetDsIpfixL3Ipv6HashKey(V, srcCategoryIdClassfied_f,&ipv6_key, CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_SRC_CID_VALID));
            SetDsIpfixL3Ipv6HashKey(V, srcCategoryId_f, &ipv6_key,p_key->src_cid);
        }
        if(field_sel.u.ipv6.dst_cid)
        {
            SetDsIpfixL3Ipv6HashKey(V, destCategoryIdClassfied_f,&ipv6_key,CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_DST_CID_VALID));
            SetDsIpfixL3Ipv6HashKey(V, destCategoryId_f, &ipv6_key,p_key->dst_cid);
        }

        if(field_sel.u.ipv6.ip_frag)
        {
            SetDsIpfixL3Ipv6HashKey(V, fragInfo_f, &ipv6_key, SYS_IPFIX_MAP_IP_FRAG(p_key->l3_info.ip_frag));
        }
        if(field_sel.u.ipv6.ttl)
        {
            SetDsIpfixL3Ipv6HashKey(V, ttl_f, &ipv6_key,p_key->l3_info.ipv6.ttl);
        }
        if(field_sel.u.ipv6.ecn)
        {
            SetDsIpfixL3Ipv6HashKey(V, ecn_f, &ipv6_key,p_key->l3_info.ipv6.ecn);
        }
        if(field_sel.u.ipv6.flow_label)
        {
            SetDsIpfixL3Ipv6HashKey(V, ipv6FlowLabel_f, &ipv6_key,p_key->l3_info.ipv6.flow_label);
        }
        tcp_flag_mask = GetIpfixL3Ipv6HashFieldSelect(V, g1_tcpFlagsEn_f, &hash_field);
        SetDsIpfixL3Ipv6HashKey(V, tcpFlags_f, &ipv6_key, (p_key->l4_info.tcp_flags & tcp_flag_mask));
    }
    else
    {
        if(!GetIpfixL3Ipv6HashFieldSelect(V,ipAddressMode_f,&hash_field))
        {
            IPFIX_IPV6_MASK_LEN_CHECK(p_key->l3_info.ipv6.ipsa_masklen);
            IPFIX_IPV6_MASK_LEN_CHECK(p_key->l3_info.ipv6.ipda_masklen);

            IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipsa, p_key->l3_info.ipv6.ipsa_masklen);
            IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipda, p_key->l3_info.ipv6.ipda_masklen);

            IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipda);
            SetDsIpfixL3Ipv6HashKey(A, uIpDa_g1_ipDa_f, &ipv6_key, hw_ip6);

            IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipsa);
            SetDsIpfixL3Ipv6HashKey(A, uIpSa_g1_ipSa_f, &ipv6_key, hw_ip6);
        }
        else
        {
            if(p_key->l4_info.aware_tunnel_info_en)
            {
                SetDsIpfixL3Ipv6HashKey(V, isMergeKey_f, &ipv6_key, 1);
                if(field_sel.u.ipv6.vxlan_vni)
                {
                    SetDsIpfixL3Ipv6HashKey(V, uIpDa_g2_mergeDataType_f, &ipv6_key,SYS_IPFIX_MERGE_TYPE_VXLAN);
                    merge_data[0] = p_key->l4_info.vni;
                    SetDsIpfixL3Ipv6HashKey(A, uIpDa_g2_mergeData_f, &ipv6_key, merge_data);
                }
                else if(field_sel.u.ipv6.gre_key || field_sel.u.ipv6.nvgre_key)
                {
                    SetDsIpfixL3Ipv6HashKey(V, uIpDa_g2_mergeDataType_f, &ipv6_key,SYS_IPFIX_MERGE_TYPE_GRE);
                    merge_data[0] = p_key->l4_info.gre_key;
                    SetDsIpfixL3Ipv6HashKey(A, uIpDa_g2_mergeData_f, &ipv6_key, merge_data);
                }
                else
                {
                    SetDsIpfixL3Ipv6HashKey(V, uIpDa_g2_mergeDataType_f, &ipv6_key,SYS_IPFIX_MERGE_TYPE_WLAN);
                    if(field_sel.u.ipv6.wlan_radio_mac)
                    {
                        SYS_USW_SET_HW_MAC(wlan, p_key->l4_info.wlan.radio_mac);
                    }
                    if(field_sel.u.ipv6.wlan_radio_id)
                    {
                        wlan[1] = (wlan[1] & 0xFFFF) | (p_key->l4_info.wlan.radio_id & 0x1F) <<16;
                    }
                    if(field_sel.u.ipv6.wlan_ctl_packet)
                    {
                        wlan[1] = (wlan[1] & 0x1FFFFF) | (p_key->l4_info.wlan.is_ctl_pkt) << 21;
                    }
                    SetDsIpfixL3Ipv6HashKey(A, uIpDa_g2_mergeData_f, &ipv6_key, wlan);
                }
            }
            if(field_sel.u.ipv6.src_cid)
            {
                SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_srcCategoryIdClassfied_f,&ipv6_key, CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_SRC_CID_VALID));
                SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_srcCategoryId_f, &ipv6_key,p_key->src_cid);
            }
            if(field_sel.u.ipv6.dst_cid)
            {
                SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_destCategoryIdClassfied_f,&ipv6_key,CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_DST_CID_VALID));
                SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_destCategoryId_f, &ipv6_key,p_key->dst_cid);
            }

            if(field_sel.u.ipv6.ip_frag)
            {
                SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_fragInfo_f, &ipv6_key, SYS_IPFIX_MAP_IP_FRAG(p_key->l3_info.ip_frag));
            }
            if(field_sel.u.ipv6.ttl)
            {
                SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_ttl_f, &ipv6_key,p_key->l3_info.ipv6.ttl);
            }
            if(field_sel.u.ipv6.ecn)
            {
                SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_ecn_f, &ipv6_key,p_key->l3_info.ipv6.ecn);
            }
            if(field_sel.u.ipv6.flow_label)
            {
                SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_ipv6FlowLabel_f, &ipv6_key,p_key->l3_info.ipv6.flow_label);
            }

            tcp_flag_mask = GetIpfixL3Ipv6HashFieldSelect(V, g1_tcpFlagsEn_f, &hash_field);
            SetDsIpfixL3Ipv6HashKey(V, uIpSa_g2_tcpFlags_f, &ipv6_key, (p_key->l4_info.tcp_flags & tcp_flag_mask));

            IPFIX_IPV6_MASK_LEN_CHECK(p_key->l3_info.ipv6.ipsa_masklen);
            IPFIX_IPV6_MASK_LEN_CHECK(p_key->l3_info.ipv6.ipda_masklen);

            IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipsa, p_key->l3_info.ipv6.ipsa_masklen);
            IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipda, p_key->l3_info.ipv6.ipda_masklen);

            if(field_sel.u.ipv6.ip_da && field_sel.u.ipv6.ip_da_mask <= 64)
            {
                IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipda);
                SetDsIpfixL3Ipv6HashKey(A, uIpDa_g2_ipDaPrefix_f, &ipv6_key, &(hw_ip6[2]));
            }
            if(field_sel.u.ipv6.ip_sa && field_sel.u.ipv6.ip_sa_mask <= 64)
            {
                IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipsa);
                SetDsIpfixL3Ipv6HashKey(A, uIpSa_g2_ipSaPrefix_f, &ipv6_key, &(hw_ip6[2]));
            }
        }
    }
    sal_memcpy((uint8*)p_data, (uint8*)&ipv6_key, sizeof(ipv6_key));
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_ipfix_check_hash_key_valid(uint8 lchip, ctc_ipfix_data_t* p_key)
{
    uint8 is_icmp = p_key->l4_info.icmp.icmpcode || p_key->l4_info.icmp.icmp_type;
    uint8 is_igmp = !!p_key->l4_info.igmp.igmp_type;
    uint8 is_l4_port = p_key->l4_info.l4_port.dest_port || p_key->l4_info.l4_port.source_port || p_key->l4_info.tcp_flags;
    uint8 is_vxlan = !!p_key->l4_info.vni;
    uint8 is_gre = !!p_key->l4_info.gre_key;
    uint8 is_protocol = !!p_key->l4_info.type.ip_protocol;
    uint8 loop;
    CTC_MAX_VALUE_CHECK(p_key->svlan, CTC_MAX_VLAN_ID);
    CTC_MAX_VALUE_CHECK(p_key->svlan_prio, CTC_MAX_COS-1);
    CTC_MAX_VALUE_CHECK(p_key->svlan_cfi, 1);
    CTC_MAX_VALUE_CHECK(p_key->cvlan, CTC_MAX_VLAN_ID);
    CTC_MAX_VALUE_CHECK(p_key->cvlan_prio, CTC_MAX_COS-1);
    CTC_MAX_VALUE_CHECK(p_key->cvlan_cfi, 1);

    SYS_USW_FID_CHECK(p_key->fid);
    CTC_MAX_VALUE_CHECK(p_key->dir, CTC_EGRESS);

    /*l3*/
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ip_frag, CTC_IP_FRAG_MAX);
    if(p_key->l3_info.ip_frag == CTC_IP_FRAG_NON_OR_FIRST || p_key->l3_info.ip_frag == CTC_IP_FRAG_YES)
    {
        return CTC_E_INVALID_PARAM;
    }
    CTC_MAX_VALUE_CHECK(p_key->l3_info.vrfid, MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID));

    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv4.dscp, 0x3F);
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv4.ecn, 0x3);
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv4.ipda_masklen, 32);
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv4.ipsa_masklen, 32);
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv4.ip_pkt_len, 0x3FFF);

    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv6.dscp, 0x3F);
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv6.ecn, 0x3);
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv6.ipda_masklen, 128);
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv6.ipsa_masklen, 128);
    CTC_MAX_VALUE_CHECK(p_key->l3_info.ipv6.flow_label, 0xFFFFF);

    CTC_MAX_VALUE_CHECK(p_key->l3_info.mpls.label_num, CTC_IPFIX_LABEL_NUM);
    for(loop=0; loop < p_key->l3_info.mpls.label_num; loop++)
    {
        CTC_MAX_VALUE_CHECK(p_key->l3_info.mpls.label[loop].exp, 0x7);
        CTC_MAX_VALUE_CHECK(p_key->l3_info.mpls.label[loop].sbit, 1);
        CTC_MAX_VALUE_CHECK(p_key->l3_info.mpls.label[loop].label, 0xFFFFF);
    }

    if(is_protocol)
    {
        if((is_gre +is_vxlan) > 1)
        {
            return CTC_E_PARAM_CONFLICT;
        }
        if((is_gre||is_vxlan)&&(is_icmp||is_l4_port || is_igmp))
        {
             return CTC_E_PARAM_CONFLICT;
        }
    }
    else
    {
        if((is_gre  + is_icmp + is_igmp + is_vxlan + is_l4_port) > 1)
        {
             return CTC_E_PARAM_CONFLICT;
        }
    }
    CTC_MAX_VALUE_CHECK(p_key->l4_info.wlan.radio_id, 0x1f);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_ipfix_encode_hash_ad(uint8 lchip, sys_ipfix_param_t* param)
{
    DsIpfixSessionRecord_m ad_rec;
    uint32 dest_type = SYS_IPFIX_UNICAST_DEST;
    uint32 dest_chip_id = 0;
    uint32 lport = 0;
    uint32 byte_cnt[2] = {0};
    ctc_ipfix_data_t* p_key = param->p_key;

    sal_memset(&ad_rec, 0, sizeof(ad_rec));

    lport = SYS_MAP_CTC_GPORT_TO_DRV_LPORT(p_key->dest_gport);
    dest_chip_id = SYS_MAP_CTC_GPORT_TO_GCHIP(p_key->dest_gport);
    if (p_key->flags & CTC_IPFIX_DATA_L2_MCAST_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uDestinationInfo_gL2Mcast_l2McGroupId_f , &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_L2MC_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_L3_MCAST_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uDestinationInfo_gL3Mcast_l3McGroupId_f , &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_L3MC_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_BCAST_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uDestinationInfo_gBcast_floodingId_f, &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_BCAST_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_APS_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uDestinationInfo_gApsGroup_apsGroupId_f, &ad_rec, p_key->dest_group_id);
        SetDsIpfixSessionRecord(V, uDestinationInfo_gApsGroup_destType_f, &ad_rec, SYS_IPFIX_SUB_APS_DEST);
        dest_type = SYS_IPFIX_UNION_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_ECMP_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uDestinationInfo_gEcmpGroup_ecmpGroupId_f, &ad_rec, p_key->dest_group_id);
        SetDsIpfixSessionRecord(V, uDestinationInfo_gEcmpGroup_destType_f, &ad_rec, SYS_IPFIX_SUB_ECMP_DEST);
        dest_type = SYS_IPFIX_UNION_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_LINKAGG_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToLagg_linkaggGroupId_f, &ad_rec, p_key->dest_group_id);
        SetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToLagg_destType_f, &ad_rec, SYS_IPFIX_SUB_LINKAGG_DEST);
        dest_type = SYS_IPFIX_UNION_DEST;
    }
    else
    {
        SetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToNormal_destChipId_f, &ad_rec, dest_chip_id);
        SetDsIpfixSessionRecord(V, uDestinationInfo_gUcastToNormal_destId_f, &ad_rec, lport);
    }

    byte_cnt[0] = (uint32)p_key->byte_count;
    byte_cnt[1] = (uint32)(p_key->byte_count >> 32);


    SetDsIpfixSessionRecord(V, exportReason_f, &ad_rec, p_key->export_reason);
    SetDsIpfixSessionRecord(V, expired_f, &ad_rec, (p_key->export_reason==CTC_IPFIX_REASON_EXPIRED)?1:0);
    SetDsIpfixSessionRecord(V, droppedPacket_f , &ad_rec, (p_key->flags&CTC_IPFIX_DATA_DROP_DETECTED));
    SetDsIpfixSessionRecord(V, u2Type_f , &ad_rec, 1);
    SetDsIpfixSessionRecord(V, destinationType_f, &ad_rec, dest_type);
    SetDsIpfixSessionRecord(A, byteCount_f, &ad_rec, byte_cnt);
    SetDsIpfixSessionRecord(V, packetCount_f, &ad_rec, p_key->pkt_count);
    SetDsIpfixSessionRecord(V, fragment_f , &ad_rec, (p_key->flags&CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED)?1:0);
    SetDsIpfixSessionRecord(V, minTtl_f, &ad_rec, p_key->min_ttl);
    SetDsIpfixSessionRecord(V, maxTtl_f, &ad_rec, p_key->max_ttl);
    SetDsIpfixSessionRecord(V, nonFragment_f, &ad_rec, (p_key->flags&CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED)?0:1);
    SetDsIpfixSessionRecord(V, tcpFlagsStatus_f, &ad_rec, p_key->tcp_flags);
    SetDsIpfixSessionRecord(V, isMonitorEntry_f, &ad_rec, 1);
    sal_memcpy((uint8*)(&param->igr_ad_data), (uint8*)&ad_rec, sizeof(ad_rec));
    return CTC_E_NONE;
}


int32
_sys_usw_ipfix_encode_hash(uint8 lchip, sys_ipfix_param_t* param)
{
    if (p_usw_ipfix_master[lchip]->callbacks_encode[param->p_key->key_type])
    {
        CTC_ERROR_RETURN(p_usw_ipfix_master[lchip]->callbacks_encode[param->p_key->key_type](lchip, param->p_key, &(param->key_data)));
    }
    else
    {
        return CTC_E_NOT_SUPPORT;
    }
    if (MCHIP_IPFIX(lchip)->encode_ad)
    {
        CTC_ERROR_RETURN(MCHIP_IPFIX(lchip)->encode_ad(lchip, param));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_usw_ipfix_encode_hash_ad(lchip, param));
    }
    return CTC_E_NONE;
}

/**
   @brief only used for write key by key
*/

STATIC int32
_sys_usw_ipfix_get_update_entry_cnt_by_tbl_id(uint8 lchip, uint32 tbl_id, uint32* entry_cnt)
{
   uint32 update_entry_cnt = 0;

   switch(tbl_id)
   {
    case DsIpfixL3Ipv4ShortHashKey_t:
    case DsIpfixUdfShortHashKey_t:
    case DsIpfixXKeySingleHashKey_t:
    case DsIpfixL3Ipv4ShortHashKey0_t:
    case DsIpfixUdfShortHashKey0_t:
    case DsIpfixXKeySingleHashKey0_t:
    case DsIpfixL3Ipv4ShortHashKey1_t:
    case DsIpfixUdfShortHashKey1_t:
    case DsIpfixXKeySingleHashKey1_t:
        update_entry_cnt = 1;
        break;
    case DsIpfixL2HashKey_t:
    case DsIpfixL3Ipv4HashKey_t:
    case DsIpfixL3MplsHashKey_t:
    case DsIpfixL3Ipv6ShortHashKey_t:
    case DsIpfixUdfHashKey_t:
    case DsIpfixXKeyDoubleHashKey_t:
    case DsIpfixL2HashKey0_t:
    case DsIpfixL3Ipv4HashKey0_t:
    case DsIpfixL3MplsHashKey0_t:
    case DsIpfixL3Ipv6ShortHashKey0_t:
    case DsIpfixUdfHashKey0_t:
    case DsIpfixXKeyDoubleHashKey0_t:
    case DsIpfixL2HashKey1_t:
    case DsIpfixL3Ipv4HashKey1_t:
    case DsIpfixL3MplsHashKey1_t:
    case DsIpfixL3Ipv6ShortHashKey1_t:
    case DsIpfixUdfHashKey1_t:
    case DsIpfixXKeyDoubleHashKey1_t:
        update_entry_cnt = 2;
        break;
    case DsIpfixL2L3HashKey_t:
    case DsIpfixL3Ipv6HashKey_t:
    case DsIpfixXKeyQuadHashKey_t:
    case DsIpfixL2L3HashKey0_t:
    case DsIpfixL3Ipv6HashKey0_t:
    case DsIpfixXKeyQuadHashKey0_t:
    case DsIpfixL2L3HashKey1_t:
    case DsIpfixL3Ipv6HashKey1_t:
    case DsIpfixXKeyQuadHashKey1_t:
        update_entry_cnt = 4;
        break;
    default:
        break;
   }
   if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
   {
       if (tbl_id == DsIpfixUdfShortHashKey_t)
       {
           update_entry_cnt = 2;
       }
       else if (tbl_id == DsIpfixUdfHashKey_t)
       {
           update_entry_cnt = 4;
       }
   }
   if(entry_cnt)
   {
        *entry_cnt = update_entry_cnt;
   }
   return CTC_E_NONE;
}

STATIC int32
_sys_usw_ipfix_add_entry_by_index(uint8 lchip, sys_ipfix_param_t* param, uint32 index, uint8 is_key)
{
    uint32 entry_cnt = 0;
    drv_acc_in_t in;
    drv_acc_out_t out;
    ctc_ipfix_data_t* p_key = param->p_key;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));

    if(is_key)
    {
        in.data = &(param->key_data);
        in.tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_key->key_type,p_key->dir);
    }
    else
    {
        if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            in.dir = CTC_EGRESS;
            in.data = &(param->egs_ad_data);
            in.tbl_id = p_usw_ipfix_master[lchip]->short_mode ? DsIpfixSessionHalfRecord0_t : DsIpfixSessionFullRecord0_t;
            in.index = index;
            in.type = DRV_ACC_TYPE_ADD;
            in.op_type = DRV_ACC_OP_BY_INDEX;
            in.module = DRV_ACC_HASH_MODULE_IPFIX;

            CTC_ERROR_RETURN(drv_acc_api(lchip,&in, &out));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Ipfix acc out, key_index:0x%x, conflict:%d, hit:%d\n",
                                                            out.key_index, out.is_conflict, out.is_hit);
        }
        in.dir = CTC_INGRESS;
        in.tbl_id = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? (p_usw_ipfix_master[lchip]->short_mode ? DsIpfixSessionHalfRecord0_t : DsIpfixSessionFullRecord0_t) : DsIpfixSessionRecord_t;
        in.data = &(param->igr_ad_data);
    }
    in.index = index;
    in.dir = p_key->dir;
    in.type = DRV_ACC_TYPE_ADD;
    in.op_type = DRV_ACC_OP_BY_INDEX;
    in.module = DRV_ACC_HASH_MODULE_IPFIX;
    _sys_usw_ipfix_get_update_entry_cnt_by_tbl_id(lchip, in.tbl_id, &entry_cnt);
    in.value = entry_cnt;
    CTC_ERROR_RETURN(drv_acc_api(lchip,&in, &out));

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Ipfix acc out, key_index:0x%x, conflict:%d, hit:%d\n",
                                                                out.key_index, out.is_conflict, out.is_hit);
    return CTC_E_NONE;
}

 int32
_sys_usw_ipfix_delete_entry_by_index(uint8 lchip, uint8 key_type, uint32 index, uint8 dir, uint8 is_key)
{
    int32 ret = 0;
    int8 sys_hash_type = 0;
    drv_acc_in_t in;
    drv_acc_out_t out;
    void* l2_key;
    uint32 hash_key_type;
    uint32 entry_cnt = 0;
    sys_ipfix_flexed_key_t* p_flexed_key = NULL;
    uint8 hashKeyValid = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));
    in.data = mem_malloc(MEM_IPFIX_MODULE, sizeof(DsIpfixL3Ipv6HashKey_m));
    if (in.data == NULL)
    {
        return CTC_E_NO_MEMORY;
    }

    if(is_key)
    {
        in.tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(key_type,dir);
        in.index = index;  /*duet2 and TsingMa*/
        in.type = DRV_ACC_TYPE_LOOKUP;
        in.op_type = DRV_ACC_OP_BY_INDEX;
        in.dir = dir;
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "tbl_id:%d\n",in.tbl_id);
        in.module = DRV_ACC_HASH_MODULE_IPFIX;
        ret = drv_acc_api(lchip, &in, &out);
        if (ret < 0)
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"ipfix acc failed! \n");
            goto error_proc;
        }

        l2_key = (DsIpfixL2HashKey_m*)(out.data);
        hash_key_type = DRV_FROM_TMM(lchip) ? GetDsIpfixL2HashKey(V, hashKeyType0_f, l2_key) : GetDsIpfixL2HashKey(V, hashKeyType_f, l2_key);
        if(DRV_FROM_AT(lchip))
        {
            hashKeyValid = GetDsIpfixL2HashKey(V, xKeyValid0_f, l2_key);
            if(hashKeyValid && key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
            {
                return CTC_E_INVALID_PARAM;
            }
        }
        if ((!out.is_hit) || (hash_key_type == 0))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Entry not exist, out.is_hit:%d, hash_key_type:%d\n",
                              out.is_hit, hash_key_type);
            ret = CTC_E_NOT_EXIST;
            goto error_proc;
        }
        if (key_type >= CTC_IPFIX_KEY_HASH_FLEX_BASE)
        {
            p_flexed_key = ctc_vector_get(p_usw_ipfix_master[lchip]->flex_key_vec, (key_type | (dir << 7)));
            if (!p_flexed_key)
            {
                return CTC_E_NOT_EXIST;
            }
            key_type = p_flexed_key->origin_key_type;
        }
        sys_hash_type = _sys_usw_ipfix_mapping_key_type(lchip, key_type);
        if(sys_hash_type<0)
        {
            return CTC_E_INVALID_PARAM;
        }
        if ( hash_key_type !=0 && sys_hash_type != hash_key_type)
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Entry exist, but hash key type is error\n");
            ret = CTC_E_NOT_EXIST;
            goto error_proc;
        }
    }
    else
    {
          in.tbl_id = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? (p_usw_ipfix_master[lchip]->short_mode ? DsIpfixSessionHalfRecord0_t : DsIpfixSessionFullRecord0_t) : DsIpfixSessionRecord_t;
    }
    sal_memset(in.data, 0, sizeof(DsIpfixL3Ipv6HashKey_m));
    in.index = index;
    in.type = DRV_ACC_TYPE_DEL;
    in.op_type = DRV_ACC_OP_BY_INDEX;
    _sys_usw_ipfix_get_update_entry_cnt_by_tbl_id(lchip, in.tbl_id, &entry_cnt);
    in.value = entry_cnt;
    in.dir = dir;
    in.module = DRV_ACC_HASH_MODULE_IPFIX;
    CTC_ERROR_GOTO(drv_acc_api(lchip,&in, &out), ret, error_proc);

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Ipfix acc out, key_index:0x%x, conflict:%d, hit:%d\n",
                                                                out.key_index, out.is_conflict, out.is_hit);
error_proc:
    mem_free(in.data);
    return ret;
}
/**
   @brief only used for add key by key
*/
STATIC int32
_sys_usw_ipfix_add_entry_by_key(uint8 lchip, sys_ipfix_param_t* param, uint32* rst_hit, uint32* rst_key_index)
{
    int32 ret = 0;
    uint32 entry_cnt = 0;
    drv_acc_in_t in;
    drv_acc_out_t out;
    ctc_ipfix_data_t* p_key = param->p_key;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if (p_key->key_type >= CTC_IPFIX_KEY_NUM || (!DRV_FROM_AT(lchip) && p_key->key_type >= CTC_IPFIX_KEY_HASH_FLEX_BASE))
    {
        return CTC_E_INVALID_PARAM;
    }
    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));

    in.data = &(param->key_data);
    in.tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_key->key_type,p_key->dir);
    in.type = DRV_ACC_TYPE_ADD;
    in.op_type = DRV_ACC_OP_BY_KEY;
    in.tbl_id = SYS_IPFIX_GET_TABLE(in.tbl_id, p_key->dir);
    in.module = DRV_ACC_HASH_MODULE_IPFIX;
    in.dir = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? CTC_INGRESS : p_key->dir;
    in.oper_bmp = DRV_ACC_PP_EN;
    _sys_usw_ipfix_get_update_entry_cnt_by_tbl_id(lchip, in.tbl_id, &entry_cnt);
    in.value = entry_cnt;
    CTC_ERROR_RETURN(drv_acc_api(lchip, &in, &out));

    (*rst_key_index) = out.key_index;
    if (out.is_conflict)
    {
        (*rst_hit) = 0;
        ret = CTC_E_HASH_CONFLICT;
    }
    else if (out.is_hit)
    {
        (*rst_hit) = 1;
    }
    else
    {
        (*rst_hit) = 0;
        ret = CTC_E_NOT_EXIST;
    }

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Ipfix acc out, key_index:0x%x, conflict:%d, hit:%d\n",
                      out.key_index, out.is_conflict, out.is_hit);
    return ret;
}

/**
   @brief only used for lookup key by key
*/
STATIC int32
_sys_usw_ipfix_get_entry_by_key(uint8 lchip, sys_ipfix_param_t* param, uint32* rst_hit, uint32* rst_key_index)
{
    int32 ret = 0;
    drv_acc_in_t in;
    drv_acc_out_t out;
    ctc_ipfix_data_t* p_key = param->p_key;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if (p_key->key_type >= CTC_IPFIX_KEY_NUM || (!DRV_FROM_AT(lchip) && p_key->key_type >= CTC_IPFIX_KEY_HASH_FLEX_BASE))
    {
        return CTC_E_INVALID_PARAM;
    }
    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));

    in.data = &(param->key_data);
    in.tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_key->key_type,p_key->dir);
    in.type = DRV_ACC_TYPE_LOOKUP;
    in.op_type = DRV_ACC_OP_BY_KEY;
    in.tbl_id = SYS_IPFIX_GET_TABLE(in.tbl_id, p_key->dir);
    in.module = DRV_ACC_HASH_MODULE_IPFIX;
    in.dir = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? CTC_INGRESS : p_key->dir;
    in.oper_bmp = DRV_ACC_PP_EN;
    CTC_ERROR_RETURN(drv_acc_api(lchip, &in, &out));

    (*rst_key_index) = out.key_index;
    if (out.is_conflict)
    {
        (*rst_hit) = 0;
        ret = CTC_E_HASH_CONFLICT;
    }
    else if (out.is_hit)
    {
        (*rst_hit) = 1;
    }
    else
    {
        (*rst_hit) = 0;
        ret = CTC_E_NOT_EXIST;
    }

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Ipfix acc out, key_index:0x%x, conflict:%d, hit:%d\n",
                      out.key_index, out.is_conflict, out.is_hit);
    return ret;
}
STATIC int32
_sys_usw_ipfix_entry_is_local_check(uint8 lchip, ctc_ipfix_data_t* p_key)
{
    uint32 cmd = 0;
    uint32 tbl_id = 0;
    uint32 field_id = 0;
    ds_t   hash_field = {0};
    uint32 global_port_type = 0;
    uint8  mapped_lchip = 0;
#ifdef EMULATION_ENV
	return 1;
#endif
    CTC_MAX_VALUE_CHECK(p_key->field_sel_id, MCHIP_CAP(SYS_CAP_IPFIX_MAX_HASH_SEL_ID));

    switch (p_key->key_type)
    {
        case CTC_IPFIX_KEY_HASH_MAC:
            tbl_id = IpfixL2HashFieldSelect_t;
            field_id = IpfixL2HashFieldSelect_globalPortType_f;
            break;
        case CTC_IPFIX_KEY_HASH_L2_L3:
            tbl_id = IpfixL2L3HashFieldSelect_t;
            field_id = IpfixL2L3HashFieldSelect_globalPortType_f;
            break;
        case CTC_IPFIX_KEY_HASH_IPV4:
            tbl_id = IpfixL3Ipv4HashFieldSelect_t;
            field_id = IpfixL3Ipv4HashFieldSelect_globalPortType_f;
            break;
        case CTC_IPFIX_KEY_HASH_IPV6:
            tbl_id = IpfixL3Ipv6HashFieldSelect_t;
            field_id = IpfixL3Ipv6HashFieldSelect_globalPortType_f;
            break;
        case CTC_IPFIX_KEY_HASH_MPLS:
            tbl_id = IpfixL3MplsHashFieldSelect_t;
            field_id = IpfixL3MplsHashFieldSelect_globalPortType_f;
            break;

    }
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    drv_get_field(lchip, tbl_id, field_id, &hash_field, &global_port_type);
    if(CTC_IPFIX_PORT_TYPE_GPORT == global_port_type)
    {
        SYS_MAP_GPORT_TO_LCHIP1(p_key->gport,mapped_lchip);
        if(!CTC_IS_LINKAGG_PORT(p_key->gport) && \
            (lchip != mapped_lchip))
        {
            return 0;
        }

    }

    return 1;
}

/**
   @brief sync dma ipfix info
 */
STATIC int32 _sys_usw_ipfix_sync_data(uint8 lchip, void* p_dma_info)
{
    uint16 entry_num = 0;
    uint16 index = 0;
    sys_dma_info_t* p_info = (sys_dma_info_t*)p_dma_info;
    ctc_ipfix_data_t user_info;
    DmaToCpuIpfixAccFifo_m* p_temp_fifo = NULL;
    uint32 key_type = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    entry_num = p_info->entry_num;

    for (index = 0; index < entry_num; index++)
    {
        SYS_IPFIX_INIT_CHECK(lchip);

        sal_memset(&user_info, 0, sizeof(user_info));
        p_temp_fifo = (DmaToCpuIpfixAccFifo_m*)((uint8*)p_info->p_data + index * TABLE_ENTRY_SIZE(lchip, DmaToCpuIpfixAccFifo_t));

        key_type = GetDmaToCpuIpfixAccL2KeyFifo(V, hashKeyType_f, p_temp_fifo);

        switch(key_type)
        {
            case SYS_IPFIX_HASH_TYPE_L2:
                CTC_ERROR_RETURN(_sys_usw_ipfix_parser_l2_info(lchip, (DmaToCpuIpfixAccL2KeyFifo_m*)p_temp_fifo, &user_info));
                break;

            case SYS_IPFIX_HASH_TYPE_L2L3:
                CTC_ERROR_RETURN(_sys_usw_ipfix_parser_l2l3_info(lchip, (DmaToCpuIpfixAccL2L3KeyFifo_m*)p_temp_fifo, &user_info));
                break;

            case SYS_IPFIX_HASH_TYPE_IPV4:
                CTC_ERROR_RETURN(_sys_usw_ipfix_parser_l3_ipv4_info(lchip, (DmaToCpuIpfixAccL3Ipv4KeyFifo_m*)p_temp_fifo, &user_info));
                break;

            case SYS_IPFIX_HASH_TYPE_IPV6:
                CTC_ERROR_RETURN(_sys_usw_ipfix_parser_l3_ipv6_info(lchip, (DmaToCpuIpfixAccL3Ipv6KeyFifo_m*)p_temp_fifo, &user_info));
                break;

            case SYS_IPFIX_HASH_TYPE_MPLS:
                CTC_ERROR_RETURN(_sys_usw_ipfix_parser_l3_mpls_info(lchip, (DmaToCpuIpfixAccL3MplsKeyFifo_m*)p_temp_fifo, &user_info));
                break;

            default:
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"Invalid IPfix Record!! \n");
                break;

        }


        CTC_ERROR_RETURN(_sys_usw_ipfix_parser_ad_info(lchip, &user_info, p_temp_fifo));
        SYS_IPFIX_INIT_CHECK(lchip);

        SYS_IPFIX_LOCK(lchip);
        _sys_usw_ipfix_export_stats(lchip, user_info.export_reason, user_info.pkt_count, user_info.byte_count);
        SYS_IPFIX_UNLOCK(lchip);
        if (p_usw_ipfix_master[lchip]->ipfix_cb)
        {
            if (p_ipfix_cb_mutex)
            {
                sal_mutex_lock(p_ipfix_cb_mutex);
            }
            p_usw_ipfix_master[lchip]->ipfix_cb(&user_info, p_usw_ipfix_master[lchip]->user_data);
            if (p_ipfix_cb_mutex)
            {
                sal_mutex_unlock(p_ipfix_cb_mutex);
            }
        }

    }
    return CTC_E_NONE;
}
int32 sys_usw_ipfix_sync_data(uint8 lchip, void* p_dma_info)
{
    if (MCHIP_IPFIX(lchip)->sync_data)
    {
        CTC_ERROR_RETURN(MCHIP_IPFIX(lchip)->sync_data(lchip, p_dma_info));
    }
    else
    {
        return _sys_usw_ipfix_sync_data(lchip, p_dma_info);
    }
    return CTC_E_NONE;
}
#define __cpu_interface_api__

/**
   @brief only used for lookup key by key
*/
int32
sys_usw_ipfix_get_entry_by_key(uint8 lchip, ctc_ipfix_data_t* p_key, uint32* p_rst_hit, uint32* p_rst_key_index)
{
    sys_ipfix_param_t param;
    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_key);
    SYS_IPFIX_CHECK_DIR(p_key->dir);

    sal_memset(&param, 0, sizeof(param));
    param.p_key = p_key;
    if (p_key->key_type >= CTC_IPFIX_KEY_NUM || (!DRV_FROM_AT(lchip) && p_key->key_type >= CTC_IPFIX_KEY_HASH_FLEX_BASE))
    {
        return CTC_E_INVALID_PARAM;
    }

    if(p_key->key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
    {
        CTC_ERROR_RETURN(_sys_usw_ipfix_encode_hash(lchip, &param));
    }
    else
    {
        if(MCHIP_IPFIX(lchip)->ipfix_encode_xkey_hash)
        {
            CTC_ERROR_RETURN(MCHIP_IPFIX(lchip)->ipfix_encode_xkey_hash(lchip, &param));
        }
    }
    CTC_ERROR_RETURN(_sys_usw_ipfix_get_entry_by_key(lchip, &param, p_rst_hit, p_rst_key_index));

    return CTC_E_NONE;
}

/**
   @brief  used for lookup key by index
*/
int32
sys_usw_ipfix_get_entry_by_index(uint8 lchip, uint32 index, uint8 dir, uint8 key_type, ctc_ipfix_data_t* p_out)
{
    int32 ret = 0;
    drv_acc_in_t in;
    drv_acc_out_t out;
    int8 hashKeyType =0;
    int8 sys_hash_type = 0;
    DsIpfixL2HashKey_m* l2_key =NULL;
    uint32 ipfix_max_entry_num = 0;
    sys_ipfix_flexed_key_t* p_flexed_key = NULL;
    uint8 hashKeyValid = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_IPFIX_CHECK_DIR(dir);
    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_out);

    p_out->key_type = key_type;
    p_out->dir = dir;
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &ipfix_max_entry_num));
    if (index > (ipfix_max_entry_num-1))
    {
        return CTC_E_INVALID_PARAM;
    }

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "type:%d, index:%d\n", p_out->key_type, index);

    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));

    in.tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(key_type,dir);
    in.dir = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? CTC_INGRESS : dir;
    in.index = index;
    in.type = DRV_ACC_TYPE_LOOKUP;
    in.op_type = DRV_ACC_OP_BY_INDEX;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "tbl_id:%d\n",in.tbl_id);
    in.module = DRV_ACC_HASH_MODULE_IPFIX;
    ret = drv_acc_api(lchip, &in, &out);
    if (ret < 0)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"ipfix acc failed! \n");
        return ret;
    }

    l2_key = (DsIpfixL2HashKey_m*)(out.data);
    hashKeyType = DRV_FROM_TMM(lchip) ? GetDsIpfixL2HashKey(V, hashKeyType0_f, l2_key) : GetDsIpfixL2HashKey(V, hashKeyType_f, l2_key);
    if(DRV_FROM_AT(lchip))
    {
        hashKeyValid = GetDsIpfixL2HashKey(V, xKeyValid0_f, l2_key);
        if(hashKeyValid && key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    if ((!out.is_hit) || (hashKeyType == 0))
    {
        return CTC_E_NOT_EXIST;
    }
    if (key_type >= CTC_IPFIX_KEY_HASH_FLEX_BASE)
    {
        p_flexed_key = ctc_vector_get(p_usw_ipfix_master[lchip]->flex_key_vec, (key_type | (dir << 7)));
        if (!p_flexed_key)
        {
            return CTC_E_NOT_EXIST;
        }
        key_type = p_flexed_key->origin_key_type;
    }
    sys_hash_type = _sys_usw_ipfix_mapping_key_type(lchip, key_type);
    if(sys_hash_type<0)
    {
        return CTC_E_INVALID_PARAM;
    }
    if ( hashKeyType !=0 && sys_hash_type != hashKeyType)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Entry exist, but hash key type is error\n");
        return CTC_E_NOT_EXIST;
    }

    CTC_ERROR_RETURN(MCHIP_IPFIX(lchip)->decode_key_ad(lchip, p_out, 0, (void*)out.data));

    return CTC_E_NONE;
}


/**
   @brief  used for lookup ad by index
*/
int32
sys_usw_ipfix_get_ad_by_index(uint8 lchip, uint32 index, ctc_ipfix_data_t* p_out)
{
    int32 ret = 0;
    drv_acc_in_t in;
    drv_acc_out_t out;
    uint32 ipfix_max_entry_num = 0;

    SYS_IPFIX_INIT_CHECK(lchip);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "index:0x%x\n", index);

    CTC_PTR_VALID_CHECK(p_out);
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &ipfix_max_entry_num));
    if (index > (ipfix_max_entry_num-1))
    {
        return CTC_E_INVALID_PARAM;

    }

    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));


    in.tbl_id = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? (p_usw_ipfix_master[lchip]->short_mode ? DsIpfixSessionHalfRecord0_t : DsIpfixSessionFullRecord0_t) : DsIpfixSessionRecord_t;
    in.tbl_id=_sys_usw_ipfix_get_tbl_id_by_dir(lchip, in.tbl_id, p_out->dir);
    in.dir = p_out->dir;
    in.index = index;
    in.type = DRV_ACC_TYPE_LOOKUP;
    in.op_type = DRV_ACC_OP_BY_INDEX;
    in.module = DRV_ACC_HASH_MODULE_IPFIX;
    ret = drv_acc_api(lchip, &in, &out);
    if (ret < 0)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"ipfix acc failed! \n");
        return ret;
    }

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Ipfix acc out, key_index:0x%x, conflict:%d, hit:%d\n",
        out.key_index, out.is_conflict, out.is_hit);

    if (!out.is_hit)
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(MCHIP_IPFIX(lchip)->decode_key_ad(lchip, p_out, 1, (void*)out.data));

    return CTC_E_NONE;
}

/**
   @brief only used for write key by key
*/

int32
sys_usw_ipfix_add_entry_by_key(uint8 lchip, ctc_ipfix_data_t* p_key)
{
    int32 ret = CTC_E_NONE;
    uint32 rst_hit = 0;
    uint32 rst_hit_key_index = 0;
    sys_ipfix_param_t param;
    uint16 loop = 1;
    uint16 hashsalt_thd = 4095;
    uint32 cmd = 0;
    IpfixShortIpv4HashFieldSelect_m v4_short_hash_field;
    ctc_ipfix_hash_field_sel_t field_sel;
    uint8 flex_data_type;
    uint16 tmp[8] = {4095, 0, 4095, 3, 63, 1023, 4095, 0};
    sal_memset(&field_sel, 0, sizeof(field_sel));

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_key);
    SYS_IPFIX_CHECK_DIR(p_key->dir);

    sal_memset(&param, 0, sizeof(param));
    param.p_key = p_key;

    if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && (CTC_EGRESS == p_key->dir))
    {
        return CTC_E_INVALID_PARAM;
    }
    SYS_IPFIX_LOCK(lchip);

    /* entry is not local, do nothing*/
    if(!_sys_usw_ipfix_entry_is_local_check(lchip, p_key))
    {
        SYS_IPFIX_UNLOCK(lchip);
        return CTC_E_NONE;
    }
    if (p_key->key_type >= CTC_IPFIX_KEY_NUM || (!DRV_FROM_AT(lchip) && p_key->key_type >= CTC_IPFIX_KEY_HASH_FLEX_BASE))
    {
        SYS_IPFIX_UNLOCK(lchip);
        return CTC_E_INVALID_PARAM;
    }


    if (DRV_FROM_TMM(lchip))
    {
        uint32 entry_num = 0;
        sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL3Ipv4ShortHashKey_t, &entry_num);
        if (sys_usw_ipfix_get_flow_cnt(lchip) >= entry_num)
        {
            SYS_IPFIX_UNLOCK(lchip);
            return CTC_E_NO_RESOURCE;
        }
    }
    else
    {
        if (sys_usw_ipfix_get_flow_cnt(lchip) >= SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_IPFIX))
        {
            SYS_IPFIX_UNLOCK(lchip);
            return CTC_E_NO_RESOURCE;
        }
    }
    CTC_ERROR_GOTO(_sys_usw_ipfix_check_hash_key_valid(lchip, p_key), ret, error_pro);

    if(p_key->key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
    {
        CTC_ERROR_GOTO(_sys_usw_ipfix_encode_hash(lchip, &param), ret, error_pro);
    }
    else
    {
        if(MCHIP_IPFIX(lchip)->ipfix_encode_xkey_hash)
        {
            CTC_ERROR_GOTO(MCHIP_IPFIX(lchip)->ipfix_encode_xkey_hash(lchip, &param), ret, error_pro);
        }
        if (MCHIP_IPFIX(lchip)->encode_ad)
        {
            CTC_ERROR_GOTO(MCHIP_IPFIX(lchip)->encode_ad(lchip, &param), ret, error_pro);
        }
    }
    if (!DRV_FROM_TMM(lchip))
    {
        ret = _sys_usw_ipfix_get_entry_by_key(lchip, &param, &rst_hit, &rst_hit_key_index);//lookup
        if (ret && ret != CTC_E_NOT_EXIST)
        {
            goto error_pro;
        }
        goto add_key_pro;
    }
    ret = _sys_usw_ipfix_add_entry_by_key(lchip, &param, &rst_hit, &rst_hit_key_index);//add by key
    if ((ret && ret != CTC_E_NOT_EXIST) && (!(param.p_key->flags & CTC_IPFIX_DATA_RESOLVE_HASH_CONFLICT)))
    {
        goto error_pro;
    }
    if (DRV_FROM_AT(lchip) && (param.p_key->flags & CTC_IPFIX_DATA_RESOLVE_HASH_CONFLICT) && (ret == CTC_E_HASH_CONFLICT))
    {
        uint16 loop_i = 0;
        uint32  cfg_table_id = 0;
        DsIpfixConfig0_m  ipfix_cfg;
        uint32  learning_disable[SYS_IPFIX_FLOW_CONFIG_SIZE/CTC_UINT32_BITS] = {0};
        cfg_table_id = (p_key->dir == CTC_INGRESS) ? DsIpfixConfig0_t : DsIpfixConfig1_t;
        if (p_key->key_type == CTC_IPFIX_KEY_HASH_IPV4_SINGLE)
        {
            cmd = DRV_IOR(IpfixShortIpv4HashFieldSelect0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &v4_short_hash_field), ret, error_pro);
            flex_data_type = GetIpfixShortIpv4HashFieldSelect(V, flexDataType_f,  &v4_short_hash_field);
            hashsalt_thd = tmp[flex_data_type];
            if (!hashsalt_thd)
            {
                ret = CTC_E_NOT_SUPPORT;
                goto error_pro;
            }
        }
        /* hardware learning disable*/
        for(loop_i=0; loop_i < SYS_IPFIX_FLOW_CONFIG_SIZE; loop_i++) 
        {
            cmd = DRV_IOR(cfg_table_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &ipfix_cfg));
            if (GetDsIpfixConfig(V, sessionNumLimitEn_f, &ipfix_cfg))
            {
                CTC_BMP_SET(learning_disable, loop_i);
                continue;
            }
            SetDsIpfixConfig(V, sessionNumLimitEn_f, &ipfix_cfg, 1);
            cmd = DRV_IOW(cfg_table_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &ipfix_cfg));
        }
        do
        {
            p_key->hash_salt = loop;
            CTC_ERROR_GOTO(_sys_usw_ipfix_encode_hash(lchip, &param), ret, error_pro);
            ret = _sys_usw_ipfix_add_entry_by_key(lchip, &param, &rst_hit, &rst_hit_key_index);//add by key
            loop++;
        }
        while ((ret == CTC_E_HASH_CONFLICT) && (loop <= hashsalt_thd));
        /* hardware learning enable*/
        for(loop_i=0; loop_i < SYS_IPFIX_FLOW_CONFIG_SIZE; loop_i++)
        {
            if (CTC_BMP_ISSET(learning_disable, loop_i))
            {
                continue;
            }
            cmd = DRV_IOR(cfg_table_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &ipfix_cfg));
            SetDsIpfixConfig(V, sessionNumLimitEn_f, &ipfix_cfg, 0);
            cmd = DRV_IOW(cfg_table_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &ipfix_cfg));
        }

        if (loop <= hashsalt_thd)
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "%-22s: %d\n", "hash_salt", (p_key->hash_salt));
        }
        else
        {
            SYS_IPFIX_UNLOCK(lchip);
            return CTC_E_NOT_EXIST;
        }
    }
add_key_pro:
    if(!rst_hit)
    {
        CTC_ERROR_GOTO(_sys_usw_ipfix_add_entry_by_index(lchip, &param, rst_hit_key_index, 0), ret, error_pro);//add ad by index
        if (!DRV_FROM_TMM(lchip))
        {
            CTC_ERROR_GOTO(_sys_usw_ipfix_add_entry_by_index(lchip, &param, rst_hit_key_index, 1), ret, error_pro);//add key by index
        }
    }
    else
    {
        ret = CTC_E_EXIST;
    }

error_pro:
    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}

/**
   @brief only used for delete key by key
*/
int32
sys_usw_ipfix_delete_entry_by_key(uint8 lchip, ctc_ipfix_data_t* p_key)
{
    uint32 type = 0;
    uint32 rst_hit = 0;
    uint32 rst_key_index = 0;
    int32 ret = CTC_E_NONE;
    sys_ipfix_param_t param;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_key);
    SYS_IPFIX_CHECK_DIR(p_key->dir);
    IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipsa, p_key->l3_info.ipv4.ipsa_masklen);
    IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipda, p_key->l3_info.ipv4.ipda_masklen);
    IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipsa, p_key->l3_info.ipv6.ipsa_masklen);
    IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipda, p_key->l3_info.ipv6.ipda_masklen);
    sal_memset(&param, 0, sizeof(param));
    param.p_key = p_key;
    if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && (CTC_EGRESS == p_key->dir))
    {
        return CTC_E_INVALID_PARAM;
    }

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "type:%d\n", type);

    SYS_IPFIX_LOCK(lchip);
    /* entry is not local, do nothing*/
    if(!_sys_usw_ipfix_entry_is_local_check(lchip, p_key))
    {
        SYS_IPFIX_UNLOCK(lchip);
        return CTC_E_NONE;
    }

    type = p_key->key_type;
    if (type >= CTC_IPFIX_KEY_NUM)
    {
        SYS_IPFIX_UNLOCK(lchip);
        return CTC_E_INVALID_PARAM;
    }
    CTC_ERROR_GOTO(_sys_usw_ipfix_check_hash_key_valid(lchip, p_key), ret, error_pro);
    if(p_key->key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
    {
        CTC_ERROR_GOTO(_sys_usw_ipfix_encode_hash(lchip, &param), ret, error_pro);
    }
    else
    {
        if(MCHIP_IPFIX(lchip)->ipfix_encode_xkey_hash)
        {
            CTC_ERROR_GOTO(MCHIP_IPFIX(lchip)->ipfix_encode_xkey_hash(lchip, &param), ret, error_pro);
        }
        if (MCHIP_IPFIX(lchip)->encode_ad)
        {
            CTC_ERROR_GOTO(MCHIP_IPFIX(lchip)->encode_ad(lchip, &param), ret, error_pro);
        }
    }
    /* get entry by key */
    CTC_ERROR_GOTO(_sys_usw_ipfix_get_entry_by_key(lchip, &param, &rst_hit, &rst_key_index), ret, error_pro);

    if (rst_hit)
    {
        CTC_ERROR_GOTO(_sys_usw_ipfix_delete_entry_by_index(lchip, p_key->key_type, rst_key_index, p_key->dir, 1), ret, error_pro);
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            CTC_ERROR_GOTO(_sys_usw_ipfix_delete_entry_by_index(lchip, p_key->key_type, rst_key_index, CTC_INGRESS, 0), ret, error_pro);
            CTC_ERROR_GOTO(_sys_usw_ipfix_delete_entry_by_index(lchip, p_key->key_type, rst_key_index, CTC_EGRESS, 0), ret, error_pro);
        }
        else
        {
            CTC_ERROR_GOTO(_sys_usw_ipfix_delete_entry_by_index(lchip, p_key->key_type, rst_key_index, p_key->dir, 0), ret, error_pro);
        }
    }
    else
    {
        ret = CTC_E_NOT_EXIST;
    }

error_pro:
    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}

/**
   @brief only used for delete ad by index
*/
int32
sys_usw_ipfix_delete_entry_by_index(uint8 lchip, uint8 type, uint32 index, uint8 dir)
{
    uint32 ipfix_max_entry_num = 0;

    SYS_IPFIX_INIT_CHECK(lchip);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"index:0x%x, type:%d\n", index, type);
    SYS_IPFIX_CHECK_DIR(dir);
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &ipfix_max_entry_num));
    if (index > (ipfix_max_entry_num-1))
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(_sys_usw_ipfix_delete_entry_by_index(lchip, type, index, dir, 1));
    return CTC_E_NONE;

}

int32
sys_usw_ipfix_delete_ad_by_index(uint8 lchip, uint32 index, uint8 dir)
{
    uint32 ipfix_max_entry_num = 0;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_IPFIX_INIT_CHECK(lchip);
    SYS_IPFIX_CHECK_DIR(dir);
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &ipfix_max_entry_num));
    if (index > (ipfix_max_entry_num-1))
    {
        return CTC_E_INVALID_PARAM;
    }
    CTC_ERROR_RETURN(_sys_usw_ipfix_delete_entry_by_index(lchip, 0, index, dir, 0));

    return CTC_E_NONE;
}
/*
    only duet2 board environment need call this function,else need use _sys_usw_ipfix_traverse_dma
*/
STATIC int32
_sys_usw_ipfix_traverse_acc(uint8 lchip, ctc_ipfix_traverse_fn fn, ctc_ipfix_traverse_t* p_data, uint8 is_remove)
{
    int32 ret = 0;
    uint32 index = 0;
    uint32 count = 0;
    void* p_key = NULL;
    void* p_ad = NULL;
    ctc_ipfix_data_t ipfix_data;
    uint32 ipfix_entry_num;
    uint32 ipfix_max_entry_num = 0;
    uint32 dump_end_entry_num = 0;
    uint32 next_index = 0;
    uint16 traverse_action = 0;
    uint8 sub_idx = 0;
    uint8 hash_type[2] = {0};
    drv_acc_in_t in;
    drv_acc_out_t out;
    uint32 temp_idx;
    uint8 dir = 0;
    ctc_ipfix_traverse_t dump_info;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(p_data->user_data != NULL)
    {
        traverse_action = *(uint16*)p_data->user_data;
    }
    sal_memset(&dump_info, 0, sizeof(dump_info));
    dump_info.lchip_id = lchip;
    sal_memset(&ipfix_data, 0, sizeof(ctc_ipfix_data_t));
    sal_memset(&in, 0, sizeof(in));
    sal_memset(&out, 0, sizeof(out));
    p_key = (uint32*)mem_malloc(MEM_IPFIX_MODULE, sizeof(DsIpfixL3Ipv6HashKey_m));
    if (NULL == p_key)
    {
        return CTC_E_NO_MEMORY;
    }


    /* get 85bits bits entry num */
    CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, SYS_IPFIX_GET_TABLE(DsIpfixL2HashKey_t,dir), &ipfix_entry_num), ret, end_pro);

    if (!DRV_IS_DUET2(lchip))
    {
        ipfix_max_entry_num =  ipfix_entry_num*4; /*Ingress + Egress*/

        if (p_data->start_index < ipfix_entry_num*2 )
        {
            dir = CTC_INGRESS;
            dump_end_entry_num = ipfix_entry_num*2; /*ingress*/
        }
        else
        {
            dir = CTC_EGRESS;
            dump_end_entry_num = ipfix_max_entry_num;
        }
    }
    else
    {
        ipfix_max_entry_num = ipfix_entry_num;
        dump_end_entry_num = ipfix_max_entry_num;

    }

    in.type = DRV_ACC_TYPE_LOOKUP;
    in.op_type = DRV_ACC_OP_BY_INDEX;
    if (p_data->start_index%4)
    {

        in.tbl_id = SYS_IPFIX_GET_TABLE(DsIpfixL2HashKey_t, dir);
        in.dir = dir;
        in.index = p_data->start_index;
        in.index = DRV_IS_DUET2(lchip)? in.index: ((dir == CTC_INGRESS)?in.index / 2:in.index / 2 - 8192);
        in.module = DRV_ACC_HASH_MODULE_IPFIX;
        CTC_ERROR_GOTO(drv_acc_api(lchip, &in, &out), ret, end_pro);
        sal_memcpy(p_key, out.data, sizeof(DsIpfixL2HashKey_m));
        hash_type[0] = GetDsIpfixL2HashKey(V, hashKeyType_f, p_key);

        if ((hash_type[0] == SYS_IPFIX_HASH_TYPE_L2) ||
            (hash_type[0] == SYS_IPFIX_HASH_TYPE_IPV4) ||
            (hash_type[0] == SYS_IPFIX_HASH_TYPE_MPLS) )
        {
            in.tbl_id =DsIpfixSessionRecord_t;
            sal_memset(&out, 0, sizeof(out));
            in.dir = dir;
            in.module = DRV_ACC_HASH_MODULE_IPFIX;
            CTC_ERROR_GOTO(drv_acc_api(lchip, &in, &out), ret, end_pro);
            p_ad = out.data;

            ipfix_data.key_type = _sys_usw_ipfix_unmapping_key_type(lchip, hash_type[0]);
            MCHIP_IPFIX(lchip)->decode_key_ad(lchip, &ipfix_data, 0, p_key);
            MCHIP_IPFIX(lchip)->decode_key_ad(lchip, &ipfix_data, 1, p_ad);
            index = p_data->start_index;
            ipfix_data.key_index = index;
            IPFIX_TRAVERSE_TYPE_PROCESS(dump_info, ipfix_data.key_type, is_remove,in.dir);
            count++;
            if (count >= p_data->entry_num)
            {
                next_index = p_data->start_index + p_data->start_index%4;
                goto end_pro;
            }
        }

    }


    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "ipfix_max_entry_num = %d\n", ipfix_max_entry_num);
    index = p_data->start_index + p_data->start_index%4;
    if(index >= ipfix_max_entry_num)
    {
        goto end_pro;
    }

    do
    {

        sal_memset(&out, 0, sizeof(out));
        in.tbl_id = SYS_IPFIX_GET_TABLE(DsIpfixL3Ipv6HashKey_t, dir);
        in.dir = dir;
        in.index = index;
        in.index = DRV_IS_DUET2(lchip)? in.index: ((dir == CTC_INGRESS)?in.index / 2:in.index / 2 - 8192);
        in.module = DRV_ACC_HASH_MODULE_IPFIX;
        CTC_ERROR_GOTO(drv_acc_api(lchip, &in, &out), ret, end_pro);
        sal_memcpy(p_key, out.data, sizeof(DsIpfixL3Ipv6HashKey_m));

        hash_type[0] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType0_f, p_key);
        hash_type[1] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType1_f, p_key);
        if ((hash_type[0] != SYS_IPFIX_HASH_TYPE_INVALID) || (hash_type[1] != SYS_IPFIX_HASH_TYPE_INVALID))
        {
            for(sub_idx=0; sub_idx < 2; sub_idx++)
            {
                if(hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_INVALID)
                {
                    continue;
                }
                sal_memset(&ipfix_data, 0, sizeof(ctc_ipfix_data_t));
                sal_memset(&out, 0, sizeof(out));
                in.tbl_id = DsIpfixSessionRecord_t;
                in.dir = dir;
                in.index = index + 2*sub_idx;
                in.index = DRV_IS_DUET2(lchip)? in.index: ((dir == CTC_INGRESS)?in.index / 2:in.index / 2 - 8192);
                in.module = DRV_ACC_HASH_MODULE_IPFIX;
                CTC_ERROR_GOTO(drv_acc_api(lchip, &in, &out), ret, end_pro);
                p_ad = out.data;

                ipfix_data.key_type = _sys_usw_ipfix_unmapping_key_type(lchip, hash_type[sub_idx]);
                MCHIP_IPFIX(lchip)->decode_key_ad(lchip, &ipfix_data, 0, (DsIpfixL2HashKey_m*)p_key + sub_idx);
                MCHIP_IPFIX(lchip)->decode_key_ad(lchip, &ipfix_data, 1, p_ad);

                temp_idx = index+2*sub_idx;
                ipfix_data.key_index = temp_idx;
                IPFIX_TRAVERSE_TYPE_PROCESS(dump_info,ipfix_data.key_type, is_remove,in.dir);
                count += (hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_L2L3 || hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_IPV6) ? 2:1;

                if (index + 2*sub_idx >= ipfix_max_entry_num)
                {
                    p_data->is_end = 1;
                    goto end_pro;
                }
                else if (count >= p_data->entry_num)
                {
                    next_index = index + 2*(sub_idx +1);
                    goto end_pro;
                }

                if(hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_L2L3 || hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_IPV6)
                {
                    break;
                }
            }
        }

        index += 4;
        next_index = index;
    }while(index < dump_end_entry_num && count < p_data->entry_num);

end_pro:
    if(index >= ipfix_max_entry_num)
    {
        p_data->is_end = 1;
    }

    p_data->next_traverse_index = next_index;

    if(p_key)
    {
        mem_free(p_key);
    }

    return ret;
}

STATIC int32
_sys_usw_ipfix_traverse_dma(uint8 lchip, ctc_ipfix_traverse_fn fn, ctc_ipfix_traverse_t* p_data, uint8 is_remove)
{
    int32 ret = 0;
    uint32 index = 0;
    uint32 count = 0;
    void* p_key = NULL;
    void* p_ad = NULL;
    void* p_buffer = NULL;
    void* p_buffer_ad = NULL;
    ctc_ipfix_data_t ipfix_data;
    uint32 ipfix_entry_num = 0;
    uint32 ipfix_max_entry_num = 0;
    uint32 dump_end_entry_num = 0;
    uint32 next_index = 0;
    uint16 traverse_action = 0;
    uint8 sub_idx = 0;
    uint8 hash_type[2] = {0};
    uint32 temp_idx;
    sys_dma_tbl_rw_t dma_rw;
    drv_work_platform_type_t platform_type;
    uint32 cfg_addr = 0;
    uint32 cfg_ad_addr = 0;
    uint32 entry_cnt = 0;
    uint16 loop = 0;
    uint16 key_index = 0;
    uint8 dir = 0;
    uint8 chan_en = 0;
    uint32 cmd = 0;
    ctc_ipfix_traverse_t dump_info;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&dump_info, 0, sizeof(dump_info));
    dump_info.lchip_id = lchip;

    if(p_data->user_data != NULL)
    {
        traverse_action = *(uint16*)p_data->user_data;
    }

    sal_memset(&ipfix_data, 0, sizeof(ctc_ipfix_data_t));

    if (MCHIP_IPFIX(lchip)->traverse_dma)
    {
        CTC_ERROR_GOTO(MCHIP_IPFIX(lchip)->traverse_dma(lchip, fn, p_data, is_remove), ret, end_pro);
        return CTC_E_NONE;
    }

    MALLOC_ZERO(MEM_IPFIX_MODULE, p_buffer, 100*sizeof(DsIpfixL3Ipv6HashKey_m));
    if (NULL == p_buffer)
    {
        return CTC_E_NO_MEMORY;
    }
    MALLOC_ZERO(MEM_IPFIX_MODULE, p_buffer_ad, 200*sizeof(DsIpfixSessionRecord_m));
    if (NULL == p_buffer_ad)
    {
        mem_free(p_buffer);
        return CTC_E_NO_MEMORY;
    }

    /* get 85bits bits entry num */
    CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, SYS_IPFIX_GET_TABLE(DsIpfixL2HashKey_t,dir), &ipfix_entry_num), ret, end_pro);

    if (!DRV_IS_DUET2(lchip))
    {
        ipfix_max_entry_num =  ipfix_entry_num*4; /*Ingress + Egress*/

        if (p_data->start_index < ipfix_entry_num*2 )
        {
            dir = CTC_INGRESS;
            dump_end_entry_num = ipfix_entry_num*2; /*ingress*/
        }
        else
        {
            dir = CTC_EGRESS;
            dump_end_entry_num = ipfix_max_entry_num;
        }
    }
    else
    {
        ipfix_max_entry_num = ipfix_entry_num;
        dump_end_entry_num = ipfix_max_entry_num;
    }

    if (p_data->start_index%4)
    {
        drv_acc_in_t in;
        drv_acc_out_t out;
        sal_memset(&in, 0, sizeof(in));
        sal_memset(&out, 0, sizeof(out));

        p_key = p_buffer;
        in.tbl_id = SYS_IPFIX_GET_TABLE(DsIpfixL2HashKey_t, dir);
        in.dir = dir;
        in.type = DRV_ACC_TYPE_LOOKUP;
        in.op_type = DRV_ACC_OP_BY_INDEX;
        in.index = p_data->start_index;
        in.index = DRV_IS_DUET2(lchip)? in.index: ((dir == CTC_INGRESS)?in.index / 2:in.index / 2 - 8192);
        in.module = DRV_ACC_HASH_MODULE_IPFIX;
        CTC_ERROR_GOTO(drv_acc_api(lchip, &in, &out), ret, end_pro);
        sal_memcpy(p_key, out.data, sizeof(DsIpfixL2HashKey_m));
        hash_type[0] = GetDsIpfixL2HashKey(V, hashKeyType_f, p_key);

        if ((hash_type[0] == SYS_IPFIX_HASH_TYPE_L2) ||
            (hash_type[0] == SYS_IPFIX_HASH_TYPE_IPV4) ||
        (hash_type[0] == SYS_IPFIX_HASH_TYPE_MPLS) )
        {
            in.tbl_id = DRV_FROM_TMM(lchip) ? (p_usw_ipfix_master[lchip]->short_mode ? DsIpfixSessionHalfRecord0_t : DsIpfixSessionFullRecord0_t) : DsIpfixSessionRecord_t;
            in.dir = dir;
            sal_memset(&out, 0, sizeof(out));
            in.module = DRV_ACC_HASH_MODULE_IPFIX;
            CTC_ERROR_GOTO(drv_acc_api(lchip, &in, &out), ret, end_pro);
            p_ad = out.data;

            ipfix_data.key_type = _sys_usw_ipfix_unmapping_key_type(lchip, hash_type[0]);
            MCHIP_IPFIX(lchip)->decode_key_ad(lchip, &ipfix_data, 0, p_key);
            MCHIP_IPFIX(lchip)->decode_key_ad(lchip, &ipfix_data, 1, p_ad);
            index = p_data->start_index;
            ipfix_data.key_index = index;
            IPFIX_TRAVERSE_TYPE_PROCESS(dump_info, ipfix_data.key_type, is_remove,in.dir);
            count++;
            if (count >= p_data->entry_num)
            {
                next_index = p_data->start_index + p_data->start_index % 4;
                goto end_pro;
            }
        }

    }

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "ipfix_max_entry_num = %d\n", ipfix_max_entry_num);
    index = p_data->start_index + p_data->start_index%4;
    if(index >= ipfix_max_entry_num)
    {
        goto end_pro;
    }

    if(DRV_IS_TSINGMA(lchip) && index >= dump_end_entry_num && dir == CTC_INGRESS)
    {
        next_index = dump_end_entry_num;
        goto end_pro;
    }
    sal_memset(&dma_rw, 0, sizeof(dma_rw));
    drv_get_platform_type(lchip, &platform_type);
    sys_usw_dma_get_chan_en(lchip, SYS_DMA_TBL_RD_CHAN_ID, &chan_en);
    do
    {
        /*Notice: start_index and next_traverse_index is 85bits encoding index, for dma performance, every
        Dma operation is by 340bits */
        entry_cnt = ((index + 100*4) <= dump_end_entry_num)?100:(dump_end_entry_num - index) / 4;

        key_index = (DRV_IS_DUET2(lchip))?index:index/4;

        /*Using Dma to read data, using 340bits entry read*/
        if (chan_en)
        {
            if (platform_type == HW_PLATFORM)
            {
                CTC_ERROR_GOTO(drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, SYS_IPFIX_GET_TABLE(DsIpfixL3Ipv6HashKey_t, dir), SYS_IPFIX_GET_INDEX(key_index, dir), &cfg_addr), ret, end_pro);
                CTC_ERROR_GOTO(drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, SYS_IPFIX_GET_TABLE(DsIpfixSessionRecord_t,dir), SYS_IPFIX_GET_ADINDEX(index/2, dir), &cfg_ad_addr), ret, end_pro);
            }
            else
            {
                /*special process for uml*/
                cfg_addr = (SYS_IPFIX_GET_TABLE(DsIpfixL3Ipv6HashKey_t, dir) << 18)|SYS_IPFIX_GET_INDEX(key_index, dir);
                cfg_ad_addr = (SYS_IPFIX_GET_TABLE(DsIpfixSessionRecord_t,dir) << 18)| (SYS_IPFIX_GET_ADINDEX(index/2, dir));
            }
            dma_rw.tbl_addr = cfg_addr;
            dma_rw.entry_num = entry_cnt;
            dma_rw.entry_len = DRV_TABLE_ENTRY_SIZE(lchip, DsIpfixL3Ipv6HashKey_t);
            dma_rw.buffer = p_buffer;
            dma_rw.entry_offset = DRV_IS_DUET2(lchip)?(TABLE_ENTRY_OFFSET(lchip, DsIpfixL3Ipv6HashKey_t)<<2):TABLE_ENTRY_OFFSET(lchip, DsIpfixL3Ipv6HashKey_t);
            CTC_ERROR_GOTO(MCHIP_DMA(lchip)->dma_read_table(lchip, &dma_rw), ret, end_pro);

            dma_rw.tbl_addr = cfg_ad_addr;
            dma_rw.entry_num = entry_cnt;
            dma_rw.entry_len = 2 * DRV_TABLE_ENTRY_SIZE(lchip, DsIpfixSessionRecord_t);
            dma_rw.buffer = p_buffer_ad;
            dma_rw.entry_offset = 2* TABLE_ENTRY_OFFSET(lchip, DsIpfixSessionRecord_t);
            CTC_ERROR_GOTO(MCHIP_DMA(lchip)->dma_read_table(lchip, &dma_rw), ret, end_pro);
        }
        else
        {
            for (loop=0; loop<entry_cnt; loop++)
            {
                p_key = (uint8*)p_buffer + DRV_TABLE_ENTRY_SIZE(lchip, DsIpfixL3Ipv6HashKey_t)*loop;
                p_ad = (uint8*)p_buffer_ad + 2*DRV_TABLE_ENTRY_SIZE(lchip, DsIpfixSessionRecord_t)*loop;
                cmd = DRV_IOR(DsIpfixL3Ipv6HashKey_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, SYS_IPFIX_GET_INDEX(key_index, dir)+loop, cmd, p_key), ret, end_pro);

                cmd = DRV_IOR(DsIpfixSessionRecord_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, SYS_IPFIX_GET_ADINDEX(index/2, dir)+loop, cmd, p_ad), ret, end_pro);
            }
        }

        for(loop=0; loop < entry_cnt; loop++)
        {
            p_key = (uint8*)p_buffer + DRV_TABLE_ENTRY_SIZE(lchip, DsIpfixL3Ipv6HashKey_t)*loop;
            p_ad = (uint8*)p_buffer_ad + 2*DRV_TABLE_ENTRY_SIZE(lchip, DsIpfixSessionRecord_t)*loop;
            hash_type[0] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType0_f, p_key);
            hash_type[1] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType1_f, p_key);
            if ((hash_type[0] == SYS_IPFIX_HASH_TYPE_INVALID)&&(hash_type[1] == SYS_IPFIX_HASH_TYPE_INVALID))
            {
                continue;
            }

            for(sub_idx=0; sub_idx < 2; sub_idx++)
            {
                if(hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_INVALID)
                {
                    continue;
                }
                sal_memset(&ipfix_data, 0, sizeof(ctc_ipfix_data_t));

                ipfix_data.key_type = _sys_usw_ipfix_unmapping_key_type(lchip, hash_type[sub_idx]);

                _sys_usw_ipfix_decode_hashkey_ad(lchip, &ipfix_data, 0, (uint8*)p_key + sub_idx*DRV_TABLE_ENTRY_SIZE(lchip, DsIpfixL2HashKey_t));
                _sys_usw_ipfix_decode_hashkey_ad(lchip, &ipfix_data, 1, (uint8*)p_ad+sub_idx*DRV_TABLE_ENTRY_SIZE(lchip, DsIpfixSessionRecord_t));

                temp_idx = index+loop*4+2*sub_idx;
                ipfix_data.key_index = temp_idx;
                IPFIX_TRAVERSE_TYPE_PROCESS(dump_info,ipfix_data.key_type, is_remove,dir);
                count += (hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_L2L3 || hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_IPV6) ? 2:1;

                if (index + 2*sub_idx >= ipfix_max_entry_num) /* bug */
                {
                    p_data->is_end = 1;
                    goto end_pro;
                }
                else if (count >= p_data->entry_num)
                {

                    next_index = (index + loop*4) + 2*(sub_idx + 1);
                    goto end_pro;
                }

                if(hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_L2L3 || hash_type[sub_idx] == SYS_IPFIX_HASH_TYPE_IPV6)
                {
                    break;
                }
            }
            next_index = (index+loop*4);
        }
        index += 4*entry_cnt;
        next_index = index;

    }while(index < dump_end_entry_num && count < p_data->entry_num);

end_pro:
    if(index >= ipfix_max_entry_num)
    {
        p_data->is_end = 1;
    }

    p_data->next_traverse_index = next_index;

    if(p_buffer)
    {
        mem_free(p_buffer);
    }

    if(p_buffer_ad)
    {
        mem_free(p_buffer_ad);
    }

    return ret;
}
/**
   @brief ipfix traverse interface
*/
int32
sys_usw_ipfix_traverse(uint8 lchip, void* fn, ctc_ipfix_traverse_t* p_data, uint8 is_remove)
{
    drv_work_platform_type_t platform_type;
    int32 ret = 0;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(fn);
    CTC_PTR_VALID_CHECK(p_data);
    SYS_IPFIX_INIT_CHECK(lchip);
    LCHIP_CHECK(lchip);

    if (p_data->entry_num > SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_IPFIX))
    {
        return CTC_E_INVALID_PARAM;
    }

    SYS_IPFIX_LOCK(lchip);

    drv_get_platform_type(lchip, &platform_type);

    if (DRV_IS_DUET2(lchip) && (platform_type == HW_PLATFORM))
    {
        ret = _sys_usw_ipfix_traverse_acc(lchip, fn, p_data, is_remove);
    }
    else
    {
        ret = _sys_usw_ipfix_traverse_dma(lchip, fn, p_data, is_remove);
    }

    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_ipfix_show_status(uint8 lchip, void *user_data)
{
    uint32 count = 0;
    uint32 total = 0;
    ctc_ipfix_global_cfg_t ipfix_cfg;
    char* str[2] = {"Enable", "Disable"};
    char* str2[2] = {"Using group id", "Using vlan id"};

    SYS_IPFIX_INIT_CHECK(lchip);
    sal_memset(&ipfix_cfg, 0, sizeof(ctc_ipfix_global_cfg_t));
    CTC_ERROR_RETURN(sys_usw_ipfix_get_global_cfg(lchip, &ipfix_cfg));

    count = sys_usw_ipfix_get_flow_cnt(lchip);
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL2HashKey_t, &total));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %u/%u\n", DRV_FROM_AT(lchip)?"Exist Flow Cnt(134bit)" : ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))? "Exist Flow Cnt(120bit)" : "Exist Flow Cnt(160bit)"),
                        count, ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))?total : (total*2)));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %u\n", "Aging Interval(s)", (ipfix_cfg.aging_interval));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %u\n", "Pkt Cnt Threshold", (ipfix_cfg.pkt_cnt));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %"PRIu64"\n", "Bytes Cnt Threshold", (ipfix_cfg.bytes_cnt));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %u\n", "Times Interval(ms)", (ipfix_cfg.times_interval));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %s\n", "Conflict Export", (ipfix_cfg.conflict_export)?str[0]:str[1]);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %s\n", "Tcp End Detect Enable", (ipfix_cfg.tcp_end_detect_en)?str[0]:str[1]);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %s\n", "New Flow Export Enable", (ipfix_cfg.new_flow_export_en)?str[0]:str[1]);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %s\n", "Sw Learning Enable", (ipfix_cfg.sw_learning_en)?str[0]:str[1]);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %s\n", "Unkown Pkt Dest Type", (ipfix_cfg.unkown_pkt_dest_type)?str2[1]:str2[0]);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %u\n", "Threshold", (ipfix_cfg.threshold));
    if(!DRV_FROM_TMM(lchip))
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %u\n", "Latency type", (ipfix_cfg.latency_type));
    }
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: %u\n", "Conflict Stats", (ipfix_cfg.conflict_cnt));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-22s: 0x%x\n", "sample profile bmp", p_usw_ipfix_master[lchip]->sip_idx_bmp);
    if (DRV_FROM_TMM(lchip))
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Export Interval(ms)", (ipfix_cfg.export_interval));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Drop Pkt Cnt", (ipfix_cfg.drop_pkt_cnt));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Jitter Thrd", (ipfix_cfg.jitter_thrd));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Latency Thrd", (ipfix_cfg.latency_thrd));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Jitter Ewma Weight", (ipfix_cfg.jitter_ewma_weight));
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Latency Ewma Weight", (ipfix_cfg.latency_ewma_weight));
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Egr Ipfix enable", !(ipfix_cfg.egs_ipfix_disable));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Short key mode", p_usw_ipfix_master[lchip]->short_mode);
        }
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Ignore Drop Reason", p_usw_ipfix_master[lchip]->ignore_drop_reason);
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Queue drop enable", (ipfix_cfg.queue_drop_en));
    }
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Dest Port Type", (ipfix_cfg.dest_port_type));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-22s: %u\n", "Mirrored packet en", (ipfix_cfg.mirror_pkt_enable));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");

    return CTC_E_NONE;
}

int32
sys_usw_ipfix_show_stats(uint8 lchip, void *user_data, uint8 is_dump_db, sal_file_t p_f)
{
    char* str1[20] = {"Expired stats", "Tcp Close stats", "PktCnt Overflow stats", "ByteCnt Overflow stats", "Ts Overflow stats", "Conflict stats",
        "New Flow stats", "Dest Change stats", "Jitter Overflow stats", "Latency Overflow stats", "TTL Change stats", "Drop Cnt Overflow stats",
        "Drop Reason Change stats", "TC Mark stats", "Dump stats", "Buffer Drop stats", "Burst stats",
        "First Latency stats", "Burst Cnt Overflow stats", "Latency Cnt Overflow stats"};
    uint8 cnt = 0;

    SYS_IPFIX_INIT_CHECK(lchip);
    
    for(cnt=0; cnt < (sizeof(str1)/sizeof(char*)); cnt++)
    {
        if (DRV_FROM_AT(lchip) && (0 == sal_strcmp(str1[cnt], "TC Mark stats")))
        {
            continue;
        }
        if(0==is_dump_db)
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-20s\n", str1[cnt]);
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-24s: %d\n", "--Export count", p_usw_ipfix_master[lchip]->exp_cnt_stats[cnt]);
            if (0 != sal_strcmp(str1[cnt], "Dump stats"))
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-24s: %"PRIu64"\n", "--Packet count", p_usw_ipfix_master[lchip]->exp_pkt_cnt_stats[cnt]);
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-24s: %"PRIu64"\n\n", "--Packet byte", p_usw_ipfix_master[lchip]->exp_pkt_byte_stats[cnt]);
            }
        }
        else
        {
            SYS_DUMP_DB_LOG(p_f,"%-20s\n", str1[cnt]);
            SYS_DUMP_DB_LOG(p_f,"%-24s: %d\n", "--Export count", p_usw_ipfix_master[lchip]->exp_cnt_stats[cnt]);
            if (0 != sal_strcmp(str1[cnt], "Dump stats"))
            {
                SYS_DUMP_DB_LOG(p_f, "%-24s: %"PRIu64"\n", "--Packet count", p_usw_ipfix_master[lchip]->exp_pkt_cnt_stats[cnt]);
                SYS_DUMP_DB_LOG(p_f, "%-24s: %"PRIu64"\n\n", "--Packet byte", p_usw_ipfix_master[lchip]->exp_pkt_byte_stats[cnt]);
            }
        }
    }
    return CTC_E_NONE;
}

void
sys_usw_ipfix_show_kset(uint8 lchip, ctc_ipfix_flex_key_t * ipfix_flex_key)
{
    uint16 loop = 0;
    const char *ipfix_key_type_str[CTC_IPFIX_KEY_HASH_FLEX_BASE] = {
    "MAC_KEY",
    "L2_L3_KEY",
    "IPV4_KEY",
    "IPV6_KEY",
    "MPLS_KEY",
    "UDF_KEY",
    "UDF_SHORT_KEY",
    "IPV4_SHORT_KEY",
    "IPV6_SHORT_KEY",
    "MPLS_SHORT_KEY",
    };

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8s  %-24s\n", "ID", "FIELD");
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------\n");
    for (loop = 0; loop < CTC_FIELD_KEY_NUM; loop++)
    {
        if (!CTC_BMP_ISSET(ipfix_flex_key->kset.w, loop))
        {
            continue;
        }
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d  %-24s\n", loop, ifp_field_str[loop]);
    }
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-16s: %s\n", "origin key type", ipfix_key_type_str[ipfix_flex_key->origin_key_type]);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-16s: %u\n", "flex key bits", ipfix_flex_key->flex_bits);
}

int32
sys_usw_ipfix_clear_stats(uint8 lchip, void *user_data)
{
    uint8 cnt = 0;

    SYS_IPFIX_INIT_CHECK(lchip);
    for(cnt=0; cnt <CTC_IPFIX_REASON_MAX; cnt++)
    {
        p_usw_ipfix_master[lchip]->exp_cnt_stats[cnt] = 0;
        p_usw_ipfix_master[lchip]->exp_pkt_cnt_stats[cnt] = 0;
        p_usw_ipfix_master[lchip]->exp_pkt_byte_stats[cnt]= 0;
    }
    return CTC_E_NONE;
}

int32
sys_usw_ipfix_set_short_key_mode(uint8 lchip, uint8 enable)
{
    uint32 cmd = 0;
    uint32 value = enable? 1 : 0;
    SYS_IPFIX_INIT_CHECK(lchip);
    if (!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }
    cmd = DRV_IOW( IpfixEngineCtl0_t, IpfixEngineCtl0_enable256kFlowMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
    cmd = DRV_IOW( IpfixEngineCtl1_t, IpfixEngineCtl1_enable256kFlowMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
    cmd = DRV_IOW( IpfixHashLookupCtl_t, IpfixHashLookupCtl_enable256kFlowMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
    cmd = DRV_IOW( IpeFwdFlowHashCtl_t, IpeFwdFlowHashCtl_enable256kFlowMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value));
    p_usw_ipfix_master[lchip]->short_mode = enable? 1 : 0;

    if (MCHIP_IPFIX(lchip)->cb_init)
    {
        CTC_ERROR_RETURN(MCHIP_IPFIX(lchip)->cb_init(lchip));
    }


    return CTC_E_NONE;
}

int32
sys_usw_ipfix_set_property(uint8 lchip, ctc_ipfix_property_t* p_ipfix_pro)
{
    int32 ret = CTC_E_NONE;
    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_ipfix_pro);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(p_ipfix_pro->type)
    {
        case CTC_IPFIX_PROP_BULK_OP:
        case CTC_IPFIX_PROP_MBURST:
        case CTC_IPFIX_PROP_HASH_CONFLICT_THRD:
        case CTC_IPFIX_PROP_LOW_LATENCY:
            SYS_IPFIX_LOCK(lchip);
            ret = MCHIP_IPFIX(lchip)->set_prop_cfg ? MCHIP_IPFIX(lchip)->set_prop_cfg(lchip, p_ipfix_pro): CTC_E_NOT_SUPPORT;
            SYS_IPFIX_UNLOCK(lchip);
            break;
        default:
            break;
    }
    return ret;
}

int32
sys_usw_ipfix_get_property(uint8 lchip, ctc_ipfix_property_t* p_ipfix_pro)
{
    int32 ret = CTC_E_NONE;
    SYS_IPFIX_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_ipfix_pro);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(p_ipfix_pro->type)
    {
        case CTC_IPFIX_PROP_BULK_OP:
        case CTC_IPFIX_PROP_BULK_MISS:
        case CTC_IPFIX_PROP_MBURST:
        case CTC_IPFIX_PROP_HASH_CONFLICT_THRD:
        case CTC_IPFIX_PROP_LOW_LATENCY:
            SYS_IPFIX_LOCK(lchip);
            ret = MCHIP_IPFIX(lchip)->get_prop_cfg ? MCHIP_IPFIX(lchip)->get_prop_cfg(lchip, p_ipfix_pro): CTC_E_NOT_SUPPORT;
            SYS_IPFIX_UNLOCK(lchip);
            break;
        default:
            break;
    }
    return ret;
}

#define __WARMBOOT__
int32
_sys_usw_ipfix_wb_sync_func(void* array_data, uint32 index, void* user_data)
{
    uint32 max_entry_cnt = 0;
    sys_ipfix_xalu_vec_t *p_ipfix = (sys_ipfix_xalu_vec_t *)array_data;
    sys_wb_ipfix_xalu_vec_t  *p_wb_ipfix;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    ctc_wb_data_t *wb_data = traversal_data->data? (ctc_wb_data_t *)traversal_data->data : (ctc_wb_data_t *)traversal_data->data1;

    max_entry_cnt =  wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);

    if (traversal_data->data)
    {
        p_wb_ipfix = (sys_wb_ipfix_xalu_vec_t *)wb_data->buffer + wb_data->valid_cnt;
        sal_memset(p_wb_ipfix, 0, sizeof(sys_wb_ipfix_xalu_vec_t));
        p_wb_ipfix->flow_cfg_id = index;
        sal_memcpy(p_wb_ipfix->xalu_type, p_ipfix->xalu_type, sizeof(p_ipfix->xalu_type));
        wb_data->valid_cnt++;
    }

    if (traversal_data->data && wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
        wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_ipfix_wb_sync_xkey_func(void* array_data, uint32 index, void* user_data)
{
    uint32 max_entry_cnt = 0;
    sys_ipfix_flexed_key_t *p_ipfix = (sys_ipfix_flexed_key_t *)array_data;
    sys_wb_ipfix_xkey_vec_t  *p_wb_ipfix;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    ctc_wb_data_t *wb_data = traversal_data->data?(ctc_wb_data_t *)traversal_data->data:(ctc_wb_data_t *)traversal_data->data1;

    max_entry_cnt =  wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);

    if (traversal_data->data)
    {
        p_wb_ipfix = (sys_wb_ipfix_xkey_vec_t *)wb_data->buffer + wb_data->valid_cnt;
        sal_memset(p_wb_ipfix, 0, sizeof(sys_wb_ipfix_xkey_vec_t));
        p_wb_ipfix->key_type = (index & 0x7f);
        p_wb_ipfix->dir = (index >> 7);
        p_wb_ipfix->mode= p_ipfix->mode;
        p_wb_ipfix->key_size= p_ipfix->key_size;
        p_wb_ipfix->origin_key_type= p_ipfix->origin_key_type;
        sal_memcpy(p_wb_ipfix->w, p_ipfix->kset.w, sizeof(p_ipfix->kset.w));
        wb_data->valid_cnt++;
    }

    if (traversal_data->data && wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
        wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}

int32
sys_usw_ipfix_wb_sync(uint8 lchip,uint32 app_id)
{
    int32 ret = CTC_E_NONE;
    sys_traverse_t user_data;
    ctc_wb_data_t wb_data = {0};
    sys_wb_ipfix_master_t* p_wb_ipfix_master = NULL;
    CTC_WB_ALLOC_BUFFER(&wb_data.buffer);
    user_data.value1 = lchip;

    SYS_IPFIX_LOCK(lchip);
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_IPFIX_SUBID_MASTER)
    {
        CTC_WB_INIT_DATA_T((&wb_data),sys_wb_ipfix_master_t, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER);
        p_wb_ipfix_master = (sys_wb_ipfix_master_t *)wb_data.buffer;
        p_wb_ipfix_master->lchip = lchip;
        p_wb_ipfix_master->version = SYS_WB_VERSION_IPFIX;
        p_wb_ipfix_master->aging_interval = p_usw_ipfix_master[lchip]->aging_interval;
        p_wb_ipfix_master->export_interval = p_usw_ipfix_master[lchip]->export_interval;
        p_wb_ipfix_master->max_ptr = p_usw_ipfix_master[lchip]->max_ptr;
        p_wb_ipfix_master->short_mode = p_usw_ipfix_master[lchip]->short_mode;
        p_wb_ipfix_master->ignore_drop_reason = p_usw_ipfix_master[lchip]->ignore_drop_reason;
        p_wb_ipfix_master->max_export_entry_num = p_usw_ipfix_master[lchip]->max_export_entry_num;
        p_wb_ipfix_master->rsv[0] = 0;
        p_wb_ipfix_master->rsv[1] = 0;
        p_wb_ipfix_master->rsv[2] = 0;
        sal_memcpy(p_wb_ipfix_master->sip_interval, p_usw_ipfix_master[lchip]->sip_interval, sizeof(uint32)*8);
        wb_data.valid_cnt = 1;
        CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER);
    }
    /*sync ipfix xalu vector*/
    if(DRV_FROM_AT(lchip))
    {
        if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_IPFIX_SUBID_XALU_VEC)
        {
            user_data.data = &wb_data;
            CTC_WB_INIT_DATA_T((&wb_data),sys_wb_ipfix_xalu_vec_t, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XALU_VEC);
            CTC_ERROR_GOTO(ctc_vector_traverse2(p_usw_ipfix_master[lchip]->xalu_vec,0, _sys_usw_ipfix_wb_sync_func, (void *)&user_data), ret, done);
            if (wb_data.valid_cnt > 0)
            {
                CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
                wb_data.valid_cnt = 0;
            }
            CTC_WB_SYNC_END_DATA(CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XALU_VEC);
        }
    }
    /*sync ipfix xdata_fk vector*/
    if(DRV_FROM_AT(lchip) && !SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_IPFIX_SUBID_XKEY_VEC)
        {
            user_data.data = &wb_data;
            CTC_WB_INIT_DATA_T((&wb_data),sys_wb_ipfix_xkey_vec_t, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XKEY_VEC);
            CTC_ERROR_GOTO(ctc_vector_traverse2(p_usw_ipfix_master[lchip]->flex_key_vec,0, _sys_usw_ipfix_wb_sync_xkey_func, (void *)&user_data), ret, done);
            if (wb_data.valid_cnt > 0)
            {
                CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
                wb_data.valid_cnt = 0;
            }
            CTC_WB_SYNC_END_DATA(CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XKEY_VEC);
        }
    }

done:
    CTC_WB_FREE_BUFFER(wb_data.buffer);
    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}


int32
sys_usw_ipfix_wb_restore(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    ctc_wb_query_t wb_query;
    sys_wb_ipfix_master_t wb_ipfix_master;
    sys_wb_ipfix_master_t* p_wb_ipfix_master = &wb_ipfix_master;
    sys_wb_ipfix_xalu_vec_t* wb_ipfix_xalu_vec = NULL;
    sys_ipfix_xalu_vec_t* sys_ipfix_xalu_vec;
    uint32  loop = 0;
    uint32  loop_j = 0;
    uint32  cmd = 0;
    uint32  classid = 0;
    DsIngressIpfixConfig_m igr_cfg;
    IpfixIngSamplingProfile_m  ipfix_sampling_cfg;
    uint32  tbl_num;
    uint32  step = IpfixIngSamplingProfile_array_1_ingSamplingMode_f - IpfixIngSamplingProfile_array_0_ingSamplingMode_f;
    uint8   dir;
    uint32  tab_id;
    uint32  sample_tab_id;
    uint32 hw_drop_report_bmp[2] = {0};
    DsIpfixConfig0_m  ipfix_cfg0;
    DsIpfixConfig1_m  ipfix_cfg1;
    DsIpfixAluProfile_m ds;
    sys_ipfix_drop_classid_t drop_classid;
    uint32 entry_cnt = 0;
    uint32 alu_profile_tbl_idx = 0;
    uint8 alu_en = 0;
    uint32 alu_profile_id = 0;
    uint32 alu_table_pos_egs[8] = {DsIpfixAluProfile01_t, DsIpfixAluProfile11_t, DsIpfixAluProfile21_t, DsIpfixAluProfile31_t,
                          DsIpfixAlu16Profile01_t, DsIpfixAlu16Profile11_t, DsIpfixAlu16Profile21_t, DsIpfixAlu16Profile31_t};
    sys_ipfix_xalu_profile_t old_xalu_profile;
    sys_wb_ipfix_xkey_vec_t* wb_ipfix_xkey_vec = NULL;
    sys_ipfix_flexed_key_t* sys_ipfix_xkey_vec;
    sal_memset(&ipfix_cfg0, 0, sizeof(ipfix_cfg0));
    sal_memset(&ipfix_cfg1, 0, sizeof(ipfix_cfg1));
    sal_memset(&drop_classid, 0, sizeof(drop_classid));
    sal_memset(&old_xalu_profile, 0, sizeof(sys_ipfix_xalu_profile_t));
    MALLOC_ZERO(MEM_IPFIX_MODULE, wb_ipfix_xalu_vec, sizeof(sys_wb_ipfix_xalu_vec_t));
    CTC_ERROR_RETURN(NULL == wb_ipfix_xalu_vec ? CTC_E_NO_MEMORY: CTC_E_NONE);
    MALLOC_ZERO(MEM_IPFIX_MODULE, wb_ipfix_xkey_vec, sizeof(sys_wb_ipfix_xkey_vec_t));
    CTC_ERROR_RETURN(NULL == wb_ipfix_xkey_vec ? CTC_E_NO_MEMORY: CTC_E_NONE);

    CTC_WB_ALLOC_BUFFER(&wb_query.buffer);

    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_ipfix_master_t, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_MASTER);

    /* set default value for new added fields, the default value may not be zeros */
    sal_memset(&wb_ipfix_master, 0, sizeof(sys_wb_ipfix_master_t));

    CTC_ERROR_GOTO(ctc_wb_query_entry(&wb_query), ret, done);

    /*restore  master*/
    if (wb_query.valid_cnt != 1 || wb_query.is_end != 1)
    {
        CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "query ipfix master error! valid_cnt: %d, is_end: %d.\n", wb_query.valid_cnt, wb_query.is_end);
        ret = CTC_E_NONE;
        goto done;
    }

    sal_memcpy((uint8*)&wb_ipfix_master, (uint8*)wb_query.buffer, wb_query.key_len + wb_query.data_len);

    if (CTC_WB_VERSION_CHECK(SYS_WB_VERSION_IPFIX, p_wb_ipfix_master->version))
    {
        ret = CTC_E_VERSION_MISMATCH;
        goto done;
    }

    if (p_usw_ipfix_master[lchip]->max_ptr != p_wb_ipfix_master->max_ptr)
    {
        ret = CTC_E_VERSION_MISMATCH;
        goto done;
    }

    p_usw_ipfix_master[lchip]->aging_interval = p_wb_ipfix_master->aging_interval;
    p_usw_ipfix_master[lchip]->export_interval = p_wb_ipfix_master->export_interval;
    p_usw_ipfix_master[lchip]->short_mode = p_wb_ipfix_master->short_mode;
    p_usw_ipfix_master[lchip]->ignore_drop_reason = p_wb_ipfix_master->ignore_drop_reason;
    p_usw_ipfix_master[lchip]->max_export_entry_num = p_wb_ipfix_master->max_export_entry_num;
    sal_memcpy(p_usw_ipfix_master[lchip]->sip_interval, p_wb_ipfix_master->sip_interval, sizeof(uint32)*8);


    /*restore sample spool*/
    for(dir=0; dir < CTC_BOTH_DIRECTION; dir++)
    {
        if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))&&(CTC_EGRESS==dir))
        {
            break;
        }
        if(dir == CTC_INGRESS)
        {
            if (DRV_IS_DUET2(lchip))
            {
                tab_id = DsIngressIpfixConfig_t;
                sample_tab_id = IpfixIngSamplingProfile_t;
            }
            else
            {
                tab_id = DsIpfixConfig0_t;
                sample_tab_id = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? IpfixSamplingProfile_t : IpfixSamplingProfile0_t;
            }

        }
        else
        {
            if (DRV_IS_DUET2(lchip))
            {
                tab_id = DsEgressIpfixConfig_t;
                sample_tab_id = IpfixEgrSamplingProfile_t;
            }
            else
            {
                tab_id = DsIpfixConfig1_t;
                sample_tab_id = IpfixSamplingProfile1_t;
            }
        }
        cmd = DRV_IOR(sample_tab_id, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_sampling_cfg), ret, done);
        CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, tab_id, &tbl_num), ret, done);
        cmd = DRV_IOR(tab_id, DRV_ENTRY_FLAG);

        for(loop=0; loop < tbl_num; loop++)
        {
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &igr_cfg), ret, done);
            if(GetDsIngressIpfixConfig(V, samplingEn_f, &igr_cfg))
            {
                uint8   sample_profile_idx = GetDsIngressIpfixConfig(V, samplingProfileIndex_f, &igr_cfg);
                sys_ipfix_sample_profile_t sample_prf;

                sample_prf.dir = dir;
                if(dir == CTC_INGRESS)
                {
                    sample_prf.interval = p_usw_ipfix_master[lchip]->sip_interval[sample_profile_idx];
                }
                else
                {
                    sample_prf.interval = p_usw_ipfix_master[lchip]->sip_interval[sample_profile_idx+MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE)];
                }
                if(DRV_FROM_TMM(lchip))
                {
                    sample_prf.mode = GetIpfixSamplingProfile(V, \
                                                array_0_samplingMode_f+step*sample_profile_idx, &ipfix_sampling_cfg);
                    sample_prf.mode |= GetIpfixSamplingProfile(V, \
                                                array_0_countBasedSamplingMode_f+step*sample_profile_idx, &ipfix_sampling_cfg) << 1;
                }
                else
                {
                    sample_prf.mode = GetIpfixIngSamplingProfile(V, \
                                                array_0_ingSamplingMode_f+step*sample_profile_idx, &ipfix_sampling_cfg);
                    sample_prf.mode |= GetIpfixIngSamplingProfile(V, \
                                                array_0_ingCountBasedSamplingMode_f+step*sample_profile_idx, &ipfix_sampling_cfg) << 1;
                }
                sample_prf.ad_index = sample_profile_idx;

                CTC_ERROR_GOTO(ctc_spool_add(p_usw_ipfix_master[lchip]->sample_spool, &sample_prf, NULL, NULL), ret, done);

            }

        }
    }

    /*restore drop classid spool*/
    if(DRV_FROM_TMM(lchip))
    {
        for(loop=0; loop < SYS_IPFIX_FLOW_CONFIG_SIZE; loop++) /* igs*/
        {
            cmd = DRV_IOR(DsIpfixConfig0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &ipfix_cfg0));
            if(!GetDsIpfixConfig0(V, recordDiscardVectorEn_f, &ipfix_cfg0))
            {
                continue;
            }
            GetDsIpfixConfig0(A, discardVectorExportBmp_f, &ipfix_cfg0, hw_drop_report_bmp);
            for(loop_j=0; loop_j<CTC_DROP_MAX;loop_j++)
            {
                if(CTC_BMP_ISSET(hw_drop_report_bmp, loop_j))
                {
                    #if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
                    sys_tmm_get_hw_drop_class_id(lchip, loop_j, CTC_INGRESS, &classid);
                    #endif
                    drop_classid.drop_reason = loop_j;
                    drop_classid.index.index = classid;
                    CTC_ERROR_GOTO(ctc_spool_add(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_INGRESS], &drop_classid, NULL, NULL), ret, done);
                }
            }
        }

        for(loop=0; loop < SYS_IPFIX_FLOW_CONFIG_SIZE; loop++) /* egs*/
        {
            cmd = DRV_IOR(DsIpfixConfig1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &ipfix_cfg1));
            if(!GetDsIpfixConfig1(V, recordDiscardVectorEn_f, &ipfix_cfg1))
            {
                continue;
            }
            GetDsIpfixConfig1(A, discardVectorExportBmp_f, &ipfix_cfg1, hw_drop_report_bmp);
            for(loop_j=0; loop_j<CTC_DROP_MAX;loop_j++)
            {
                if(CTC_BMP_ISSET(hw_drop_report_bmp, loop_j))
                {
                    #if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
                    sys_tmm_get_hw_drop_class_id(lchip, loop_j, CTC_EGRESS, &classid);
                    #endif
                    drop_classid.drop_reason = loop_j;
                    drop_classid.index.index = classid;
                    CTC_ERROR_GOTO(ctc_spool_add(p_usw_ipfix_master[lchip]->drop_classid_spool[CTC_EGRESS], &drop_classid, NULL, NULL), ret, done);
                }
            }
        }
    }

    /*restore ipfix xalu profile spool*/
    if(DRV_FROM_AT(lchip))
    {
        for(loop=0; loop < SYS_IPFIX_FLOW_CONFIG_SIZE; loop++) /* egs*/
        {
            cmd = DRV_IOR(DsIpfixConfig1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &ipfix_cfg1));
            alu_en = GetDsIpfixConfig(V, aluEn_f, &ipfix_cfg1);
            if(!alu_en)
            {
                continue;
            }
            while(alu_en)
            {
                if(alu_en & 0x1)
                {
                    alu_profile_id = GetDsIpfixConfig(V, g_0_aluProfileId_f + alu_profile_tbl_idx, &ipfix_cfg1);
                    cmd = DRV_IOR(alu_table_pos_egs[alu_profile_tbl_idx], DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, alu_profile_id, DRV_CMD_PP_EN(cmd), &ds));
                    sal_memcpy(&old_xalu_profile.ds, &ds, sizeof(DsIpfixAluProfile_m));
                    old_xalu_profile.index.index = alu_profile_id;
                    CTC_ERROR_GOTO(ctc_spool_add(p_usw_ipfix_master[lchip]->xalu_spool, &old_xalu_profile, NULL, NULL), ret, done);
                }
                alu_en = alu_en>>1;
                alu_profile_tbl_idx++;
            }
        }
    }

    /*restore ipfix xalu vector*/
    if(DRV_FROM_AT(lchip))
    {
        CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_ipfix_xalu_vec_t, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XALU_VEC);
        entry_cnt = 0;
        sal_memset(wb_ipfix_xalu_vec, 0, sizeof(sys_wb_ipfix_xalu_vec_t));
        CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8 *)wb_ipfix_xalu_vec, (uint8 *)wb_query.buffer + entry_cnt * (wb_query.key_len + wb_query.data_len), (wb_query.key_len + wb_query.data_len));
        entry_cnt++;
        sys_ipfix_xalu_vec = mem_malloc(MEM_IPFIX_MODULE, sizeof(sys_ipfix_xalu_vec_t));
        if (NULL == sys_ipfix_xalu_vec)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memcpy(sys_ipfix_xalu_vec->xalu_type, wb_ipfix_xalu_vec->xalu_type, sizeof(wb_ipfix_xalu_vec->xalu_type));
        CTC_ERROR_GOTO(ctc_vector_add(p_usw_ipfix_master[lchip]->xalu_vec, wb_ipfix_xalu_vec->flow_cfg_id, sys_ipfix_xalu_vec), ret, done);
        CTC_WB_QUERY_ENTRY_END((&wb_query));
     }
    /*restore ipfix xdata_fk vector*/
    if(DRV_FROM_AT(lchip)&& !SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_ipfix_xkey_vec_t, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XKEY_VEC);
        entry_cnt = 0;
        sal_memset(wb_ipfix_xkey_vec, 0, sizeof(sys_wb_ipfix_xkey_vec_t));
        CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8 *)wb_ipfix_xkey_vec, (uint8 *)wb_query.buffer + entry_cnt * (wb_query.key_len + wb_query.data_len), (wb_query.key_len + wb_query.data_len));
        entry_cnt++;
        sys_ipfix_xkey_vec = mem_malloc(MEM_IPFIX_MODULE, sizeof(sys_ipfix_flexed_key_t));
        if (NULL == sys_ipfix_xkey_vec)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memcpy(sys_ipfix_xkey_vec->kset.w, wb_ipfix_xkey_vec->w, sizeof(wb_ipfix_xkey_vec->w));
        sys_ipfix_xkey_vec->dir = wb_ipfix_xkey_vec->dir;
        sys_ipfix_xkey_vec->mode = wb_ipfix_xkey_vec->mode;
        sys_ipfix_xkey_vec->key_size = wb_ipfix_xkey_vec->key_size;
        sys_ipfix_xkey_vec->key_type = wb_ipfix_xkey_vec->key_type;
        sys_ipfix_xkey_vec->origin_key_type = wb_ipfix_xkey_vec->origin_key_type;

        CTC_ERROR_GOTO(ctc_vector_add(p_usw_ipfix_master[lchip]->flex_key_vec, (wb_ipfix_xkey_vec->key_type | wb_ipfix_xkey_vec->dir << 7), sys_ipfix_xkey_vec), ret, done);
        CTC_WB_QUERY_ENTRY_END((&wb_query));
     }
done:
   CTC_WB_FREE_BUFFER(wb_query.buffer);
   mem_free(wb_ipfix_xalu_vec);
   mem_free(wb_ipfix_xkey_vec);
   return ret;
}

#define __FLEX_KEY__

int32
sys_usw_ipfix_set_flex_key_fields(uint8 lchip, ctc_ipfix_flex_key_t* ipfix_flex_key)
{
    int32  ret = CTC_E_NONE;
    /*1. Sanity Check*/
    SYS_IPFIX_INIT_CHECK(lchip);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(ipfix_flex_key);
    CTC_MAX_VALUE_CHECK(ipfix_flex_key->dir, CTC_BOTH_DIRECTION-1);
    CTC_VALUE_RANGE_CHECK(ipfix_flex_key->mode, CTC_FIELD_FLEX_KEY_MODE_APPEND, CTC_FIELD_FLEX_KEY_MODE_MAX-1);

    SYS_IPFIX_LOCK(lchip);
    if (MCHIP_IPFIX(lchip)->ipfix_set_flex_key)
    {
        ret = MCHIP_IPFIX(lchip)->ipfix_set_flex_key(lchip, ipfix_flex_key);
    }
    else
    {
        ret = CTC_E_NOT_SUPPORT;
    }
    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_ipfix_get_flex_key_fields(uint8 lchip, ctc_ipfix_flex_key_t* ipfix_flex_key)
{
    int32  ret = CTC_E_NONE;
    /*1. Sanity Check*/
    SYS_IPFIX_INIT_CHECK(lchip);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(ipfix_flex_key);

    SYS_IPFIX_LOCK(lchip);
    if (MCHIP_IPFIX(lchip)->ipfix_get_flex_key)
    {
        ret = MCHIP_IPFIX(lchip)->ipfix_get_flex_key(lchip, ipfix_flex_key);
    }
    else
    {
        ret = CTC_E_NOT_SUPPORT;
    }
    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_ipfix_get_flex_key_sets(uint8 lchip, ctc_ipfix_flex_key_t* ipfix_flex_key)
{
    int32  ret = CTC_E_NONE;
    /*1. Sanity Check*/
    SYS_IPFIX_INIT_CHECK(lchip);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(ipfix_flex_key);

    SYS_IPFIX_LOCK(lchip);
    if (MCHIP_IPFIX(lchip)->ipfix_get_flex_key_sets)
    {
        ret = MCHIP_IPFIX(lchip)->ipfix_get_flex_key_sets(lchip, ipfix_flex_key);
    }
    else
    {
        ret = CTC_E_NOT_SUPPORT;
    }
    SYS_IPFIX_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_ipfix_cb_init(uint8 lchip)
{
    /*encode*/
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_encode_l2_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_encode_l2l3_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_IPV4] = _sys_usw_ipfix_encode_ipv4_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_IPV6] = _sys_usw_ipfix_encode_ipv6_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_MPLS] = _sys_usw_ipfix_encode_mpls_hashkey;

    /*decode*/
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_decode_l2_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_decode_l2l3_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_IPV4] = _sys_usw_ipfix_decode_ipv4_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_IPV6] = _sys_usw_ipfix_decode_ipv6_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_MPLS] = _sys_usw_ipfix_decode_mpls_hashkey;

    /*set hash select*/
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_set_l2_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_set_l2l3_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_IPV4] = _sys_usw_ipfix_set_ipv4_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_IPV6] =  _sys_usw_ipfix_set_ipv6_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_MPLS] =  _sys_usw_ipfix_set_mpls_hash_field_sel;

    /*get hash select*/
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_get_mac_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_get_l2l3_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_IPV4] = _sys_usw_ipfix_get_v4_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_IPV6] = _sys_usw_ipfix_get_v6_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_MPLS] = _sys_usw_ipfix_get_mpls_hash_sel;

    return CTC_E_NONE;
}
#endif
